在同一个键下有多个值的HashMap

是否有可能用一个键和两个值来实现一个HashMap。 就像HashMap一样?

请帮助我,也是通过告诉(如果没有办法)其他方式来实现以一个为关键的三个值的存储?

你可以:

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

例子

1.以列表作为值映射

 // create our map Map<string, List<Person>> peopleByForename = new HashMap<string, List<Person>>(); // populate it List<Person> people = new ArrayList<Person>(); 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.使用包装类

 // 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<string, Wrapper>(); // 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.使用一个元组

 // 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<string, Tuple2<Person, Person>>(); // 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; 

在我看来这是最好的解决scheme。

4.多个地图

 // create our maps Map<string, Person> firstPersonByForename = new HashMap<string, Person>(); Map<string, Person> secondPersonByForename = new HashMap<string, Person>(); // 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"]; 

这个解决scheme的缺点是这两个地图是不相关的,编程错误可能会导致两个地图不同步。

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

如果你很乐意使用外部库, Guava在Multimap就有这样的概念,如ArrayListMultimapHashMultimap

另一个不错的select是使用Apache Commons的MultiValuedMap 。 查看页面顶部的所有已知实现类 ,了解特定的实现。

例:

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

可以被replace

 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); 

将导致包含“A”,“B”和“C”的集合coll

从guava库和它的实现看看MultimapHashMultimap

与Map类似的集合,但可以将多个值与一个关键字相关联。 如果您使用相同的键但不同的值调用put(K,V)两次,则multimap包含键和两个值的映射。

我使用Map<KeyType, Object[]>将多个值与Map中的键相关联。 这样,我可以存储与一个键相关的不同types的多个值。 你必须保持适当的顺序插入和检索Object []。

例如:考虑,我们要存储学生信息。 关键是身份证,而我们想存储与学生关联的姓名,地址和电子邮件。

  //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]; 
 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); 

为了logging,纯JDK8解决scheme将使用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 

请注意,为了确保multithreading访问此数据结构的一致性,需要使用ConcurrentHashMapCopyOnWriteArrayList

是和不是。 解决的办法是为你的值创build一个Wrapper类,它包含与你的键对应的2(3或更多)值。

是的,这通常被称为multimap

请参阅: http : //google-collections.googlecode.com/svn/trunk/javadoc/index.html?com/google/common/collect/Multimap.html

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

要创build不可修改的多值图:

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

或者使用org.springframework.util.LinkedMultiValueMap

我无法发表保罗评论的答复,所以我在这里创build了对Vidhya的新评论:

包装将是我们想要存储为值的两个类的SuperClass

和内部包装类,我们可以把这些关联作为两个类对象的实例variables对象。

例如

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

而在HashMap中我们可以这样做,

 Map<KeyObject, WrapperObject> 

WrapperObj将有类variables: class1Obj, class2Obj

你可以隐式做到这一点。

 // 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[]>(); 

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

我更喜欢以下内容来存储任意数量的variables,而不必创build一个单独的类。

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

这是答案:):)

String key =“services_servicename”

ArrayList数据;

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

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

我有最好的结果。

你只需要创build新的HashMap就好了

HashMap servicesNameHashmap = new HashMap();

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

快乐编码:)

我习惯于用Objective C中的数据字典来做这件事情。在Java的Android上得到类似的结果很难。 我结束了创build一个自定义类,然后只是做我的自定义类的哈希映射。

 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; } } 

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

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

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

公共类testing{

 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

尝试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

值:链接,哈希,地图,Java