首页 文章

HashMap在同一个键下有多个值

提问于
浏览
163

我们是否可以使用一个键和两个值来实现HashMap . 就像HashMap一样?

请帮助我,还告诉(如果没有办法)任何其他方式实现三个值的存储,其中一个作为键?

19 回答

  • 227
    HashMap<Integer,ArrayList<String>> map = new    HashMap<Integer,ArrayList<String>>();
    
    ArrayList<String> list = new ArrayList<String>();
    list.add("abc");
    list.add("xyz");
    map.put(100,list);
    
  • -8

    如果您使用 Spring Framework . 有: org.springframework.util.MultiValueMap .

    要创建不可修改的多值映射:

    Map<String,List<String>> map = ...
    MultiValueMap<String, String> multiValueMap = CollectionUtils.toMultiValueMap(map);
    

    或者使用 org.springframework.util.LinkedMultiValueMap

  • 21
  • 2

    你可以隐含地做到这一点 .

    // Create the map. There is no restriction to the size that the array String can have
    HashMap<Integer, String[]> map = new HashMap<Integer, String[]>();
    
    //initialize a key chosing the array of String you want for your values
    map.put(1, new String[] { "name1", "name2" });
    
    //edit value of a key
    map.get(1)[0] = "othername";
    

    这非常简单有效 . 如果您想要不同类的值,则可以执行以下操作:

    HashMap<Integer, Object[]> map = new HashMap<Integer, Object[]>();
    
  • 7

    另一个不错的选择是使用Apache Commons的MultiValuedMap . 请查看页面顶部的 All Known Implementing Classes 以获取专门的实现 .

    例:

    HashMap<K, ArrayList<String>> map = new HashMap<K, ArrayList<String>>()
    

    可以替换为

    MultiValuedMap<K, String> map = new MultiValuedHashMap<K, String>();
    

    所以,

    map.put(key, "A");
    map.put(key, "B");
    map.put(key, "C");
    
    Collection<String> coll = map.get(key);
    

    会导致集合 coll 包含"A","B"和"C" .

  • 12

    我无法对Paul的评论发表回复,所以我在这里为Vidhya创建新的评论:

    对于我们想要存储为值的两个类,包装器将是 SuperClass .

    在内部包装类中,我们可以将关联作为两个类对象的实例变量对象 .

    例如

    class MyWrapper {
    
     Class1 class1obj = new Class1();
     Class2 class2obj = new Class2();
    ...
    }
    

    HashMap 我们可以这样说,

    Map<KeyObject, WrapperObject>
    

    WrapperObj 将有类变量: class1Obj, class2Obj

  • 55

    可以使用identityHashMap来完成,条件是键比较将由==运算符而不是equals()完成 .

  • 0

    仅供记录,纯JDK8解决方案将使用 Map::compute 方法:

    map.compute(key, (s, strings) -> strings == null ? new ArrayList<>() : strings).add(value);
    

    public static void main(String[] args) {
        Map<String, List<String>> map = new HashMap<>();
    
        put(map, "first", "hello");
        put(map, "first", "foo");
        put(map, "bar", "foo");
        put(map, "first", "hello");
    
        map.forEach((s, strings) -> {
            System.out.print(s + ": ");
            System.out.println(strings.stream().collect(Collectors.joining(", ")));
        });
    }
    
    private static <KEY, VALUE> void put(Map<KEY, List<VALUE>> map, KEY key, VALUE value) {
        map.compute(key, (s, strings) -> strings == null ? new ArrayList<>() : strings).add(value);
    }
    

    输出:

    bar: foo
    first: hello, foo, hello
    

    请注意,为确保多个线程访问此数据结构时的一致性,例如需要使用 ConcurrentHashMapCopyOnWriteArrayList .

  • 0

    这是答案:)):)

    String key= "services_servicename"

    ArrayList数据;

    for(int i = 0; i lesssthen data.size(); i){

    HashMap<String, String> servicesNameHashmap = new HashMap<String, String>();
            servicesNameHashmap.put(key,data.get(i).getServiceName());
            mServiceNameArray.add(i,servicesNameHashmap);   }
    

    我获得了最好的成绩 .

    你只需要创建新的HashMap

    HashMap servicesNameHashmap = new HashMap();

    在你的For循环中 . 它将具有相同的效果,如相同的键和多个值 .

    快乐编码:)

  • 3

    我们可以创建一个具有多个键或值的类,该类的对象可以用作map中的参数 . 你可以参考https://stackoverflow.com/a/44181931/8065321

  • 0

    我使用 Map<KeyType, Object[]> 将多个值与Map中的键相关联 . 这样,我可以存储与密钥相关联的不同类型的多个值 . 您必须通过维护从Object []插入和检索的正确顺序来注意 .

    示例:考虑,我们要存储学生信息 . 密钥是id,而我们希望存储与学生相关的姓名,地址和电子邮件 .

    //To make entry into Map
            Map<Integer, String[]> studenMap = new HashMap<Integer, String[]>();
            String[] studentInformationArray = new String[]{"name", "address", "email"};
            int studenId = 1;
            studenMap.put(studenId, studentInformationArray);
    
            //To retrieve values from Map
            String name = studenMap.get(studenId)[1];
            String address = studenMap.get(studenId)[2];
            String email = studenMap.get(studenId)[3];
    
  • 0

    不,不仅仅是 HashMap . 你基本上需要从一个键到一组值的 HashMap .

    如果您乐意使用外部库,GuavaMultimap中具有完整的概念,具有ArrayListMultimapHashMultimap等实现 .

  • 0

    你可以:

    • 使用具有列表作为值的 Map . Map<KeyType, List<ValueType>> .

    • 创建一个新的包装类,并将此包装器的实例放在 Map 中 . Map<KeyType, WrapperType> .

    • 使用类似元组(保存创建大量包装器) . Map<KeyType, Tuple<Value1Type, Value2Type>> .

    • 并排使用多个 Map .


    例子

    1. Map with list as the value

    // create our map
    Map<String, List<Person>> peopleByForename = new HashMap<>();    
    
    // populate it
    List<Person> people = new ArrayList<>();
    people.add(new Person("Bob Smith"));
    people.add(new Person("Bob Jones"));
    peopleByForename.put("Bob", people);
    
    // read from it
    List<Person> bobs = peopleByForename["Bob"];
    Person bob1 = bobs[0];
    Person bob2 = bobs[1];
    

    这种方法的缺点是列表不一定只有两个值 .

    2. Using wrapper class

    // define our wrapper
    class Wrapper {
        public Wrapper(Person person1, Person person2) {
           this.person1 = person1;
           this.person2 = person2;
        }
    
        public Person getPerson1 { return this.person1; }
        public Person getPerson2 { return this.person2; }
    
        private Person person1;
        private Person person2;
    }
    
    // create our map
    Map<String, Wrapper> peopleByForename = new HashMap<>();
    
    // populate it
    Wrapper people = new Wrapper()
    peopleByForename.put("Bob", new Wrapper(new Person("Bob Smith"),
                                            new Person("Bob Jones"));
    
    // read from it
    Wrapper bobs = peopleByForename["Bob"];
    Person bob1 = bobs.Person1;
    Person bob2 = bobs.Person2;
    

    这种方法的缺点是你必须为所有这些非常简单的容器类编写大量的样板代码 .

    3. Using a tuple

    // you'll have to write or download a Tuple class in Java, (.NET ships with one)
    
    // create our map
    Map<String, Tuple2<Person, Person> peopleByForename = new HashMap<>();
    
    // populate it
    peopleByForename.put("Bob", new Tuple2(new Person("Bob Smith",
                                           new Person("Bob Jones"));
    
    // read from it
    Tuple<Person, Person> bobs = peopleByForename["Bob"];
    Person bob1 = bobs.Item1;
    Person bob2 = bobs.Item2;
    

    在我看来,这是最好的解决方案 .

    4. Multiple maps

    // create our maps
    Map<String, Person> firstPersonByForename = new HashMap<>();
    Map<String, Person> secondPersonByForename = new HashMap<>();
    
    // populate them
    firstPersonByForename.put("Bob", new Person("Bob Smith"));
    secondPersonByForename.put("Bob", new Person("Bob Jones"));
    
    // read from them
    Person bob1 = firstPersonByForename["Bob"];
    Person bob2 = secondPersonByForename["Bob"];
    

    这个解决方案的缺点是两个 Map 相关并不明显,程序错误可能会看到两个 Map 不同步 .

  • 2

    我习惯于在Objective C中使用数据字典这样做 . 在Android for Java中获取类似的结果更难 . 我最终创建了一个自定义类,然后只是做了我的自定义类的hashmap .

    public class Test1 {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.addview);
    
    //create the datastring
        HashMap<Integer, myClass> hm = new HashMap<Integer, myClass>();
        hm.put(1, new myClass("Car", "Small", 3000));
        hm.put(2, new myClass("Truck", "Large", 4000));
        hm.put(3, new myClass("Motorcycle", "Small", 1000));
    
    //pull the datastring back for a specific item.
    //also can edit the data using the set methods.  this just shows getting it for display.
        myClass test1 = hm.get(1);
        String testitem = test1.getItem();
        int testprice = test1.getPrice();
        Log.i("Class Info Example",testitem+Integer.toString(testprice));
    }
    }
    
    //custom class.  You could make it public to use on several activities, or just include in the activity if using only here
    class myClass{
        private String item;
        private String type;
        private int price;
    
        public myClass(String itm, String ty, int pr){
            this.item = itm;
            this.price = pr;
            this.type = ty;
        }
    
        public String getItem() {
            return item;
        }
    
        public void setItem(String item) {
            this.item = item;
        }
    
        public String getType() {
            return item;
        }
    
        public void setType(String type) {
            this.type = type;
        }
    
        public int getPrice() {
            return price;
        }
    
        public void setPrice(int price) {
            this.price = price;
        }
    
    }
    
  • 5

    最简单的方法是使用谷歌收藏库:

    import com.google.common.collect.ArrayListMultimap;导入com.google.common.collect.Multimap;

    公共课测试{

    public static void main(final String[] args) {
    
        // multimap can handle one key with a list of values
        final Multimap<String, String> cars = ArrayListMultimap.create();
        cars.put("Nissan", "Qashqai");
        cars.put("Nissan", "Juke");
        cars.put("Bmw", "M3");
        cars.put("Bmw", "330E");
        cars.put("Bmw", "X6");
        cars.put("Bmw", "X5");
    
        cars.get("Bmw").forEach(System.out::println);
    
        // It will print the:
        // M3
        // 330E
        // X6
        // X5
    }
    

    }

    maven链接:https://mvnrepository.com/artifact/com.google.collections/google-collections/1.0-rc2

    更多关于:http://tomjefferys.blogspot.be/2011/09/multimaps-google-guava.html

  • 0

    看看guava-libraries中的 Multimap 及其实现 - HashMultimap

    类似于Map的集合,但可以将多个值与单个键相关联 . 如果使用相同的键但不同的值调用put(K,V)两次,则multimap包含从键到两个值的映射 .

  • 3

    是的,不是 . 解决方案是为您的值构建一个Wrapper clas,其中包含与您的密钥对应的2(3个或更多)值 .

  • 0

    我更喜欢以下内容来存储任意数量的变量,而无需创建单独的类 .

    final public static Map<String, Map<String, Float>> myMap    = new HashMap<String, Map<String, Float>>();
    
  • 1

    试试 LinkedHashMap ,样本:

    Map<String,String> map = new LinkedHashMap<String,String>();    
    map.put('1','linked');map.put('1','hash');    
    map.put('2','map');map.put('3','java');..
    

    输出:

    键:1,1,2,3值:链接,哈希, Map ,java

相关问题