HashMap在同一个键下有多个值

vid*_*hya 189 java

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

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

Pau*_*ane 256

你可以:

  1. 使用列表作为值的地图.Map<KeyType, List<ValueType>>.
  2. 创建一个新的包装类,并将此包装器的实例放在地图中.Map<KeyType, WrapperType>.
  3. 使用像类这样的元组(保存创建大量的包装器).Map<KeyType, Tuple<Value1Type, Value2Type>>.
  4. 并排使用多个地图.

例子

1.以列表作为值进行映射

// 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];
Run Code Online (Sandbox Code Playgroud)

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

2.使用包装类

// 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.get("Bob");
Person bob1 = bobs.getPerson1;
Person bob2 = bobs.getPerson2;
Run Code Online (Sandbox Code Playgroud)

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

3.使用元组

// 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;
Run Code Online (Sandbox Code Playgroud)

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

4.多个地图

// 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"];
Run Code Online (Sandbox Code Playgroud)

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


Jon*_*eet 59

不,不只是作为一个HashMap.你基本上需要HashMap从一个键到一组值.

如果你乐于使用外部库,番石榴具有正是这个概念Multimap与实现,比如ArrayListMultimapHashMultimap.

  • @Deepak:我建议你自己尝试创建一个例子,如果你遇到困难,请提出一个问题,包括你所拥有的代码.你会从中学到更多东西. (9认同)
  • @Deepak:搜索番石榴多图示例,你会找到示例代码. (2认同)

Mat*_*kan 22

另一个不错的选择是使用Apache Commons的MultiValuedMap.查看页面顶部的所有已知实现类,以获得专门的实现.

例:

HashMap<K, ArrayList<String>> map = new HashMap<K, ArrayList<String>>()
Run Code Online (Sandbox Code Playgroud)

可以替换为

MultiValuedMap<K, String> map = new MultiValuedHashMap<K, String>();
Run Code Online (Sandbox Code Playgroud)

所以,

map.put(key, "A");
map.put(key, "B");
map.put(key, "C");

Collection<String> coll = map.get(key);
Run Code Online (Sandbox Code Playgroud)

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


Boz*_*zho 13

看看Multimap番石榴图书馆及其实施 -HashMultimap

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


Sud*_*SMD 7

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];
Run Code Online (Sandbox Code Playgroud)

  • 对我来说,这是最好的答案。它更简单、更简洁、更少抽象。 (2认同)

Jan*_*amu 6

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);
Run Code Online (Sandbox Code Playgroud)


Jor*_*ney 5

最简单的方法是使用谷歌集合库:

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

public class Test {

    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
    }

}
Run Code Online (Sandbox Code Playgroud)

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

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


Igo*_*bak 5

如果您使用Spring 框架。有:org.springframework.util.MultiValueMap

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

Map<String,List<String>> map = ...
MultiValueMap<String, String> multiValueMap = CollectionUtils.toMultiValueMap(map);
Run Code Online (Sandbox Code Playgroud)

或使用 org.springframework.util.LinkedMultiValueMap