1KeyMultiValues
1KeyMultiValues
com/questions/4956844/hashmap-with-multiple-values-
under-the-same-key
Is it possible for us to implement a HashMap with one key and two values. Just as
HashMap?
Examples
// 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];
The disadvantage with this approach is that the list is not bound to exactly two
values.
// populate it
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;
The disadvantage to this approach is that you have to write a lot of
boiler-plate code for all of these very simple container classes.
3. Using a tuple
// you'll have to write or download a Tuple class in Java, (.NET ships with one)
// 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;
This is the best solution in my opinion.
4. Multiple maps
// populate them
firstPersonByForename.put("Bob", new Person("Bob Smith"));
secondPersonByForename.put("Bob", new Person("Bob Jones"));
*************************************************************
No, not just as a HashMap. You'd basically need a HashMap from a key to
a collection of values.
If you're happy to use external libraries, Guava has exactly this concept in
Multimap with implementations such as ArrayListMultimap, HashMultimap,
LinkedHashMultimap etc.
System.out.println(nameToNumbers.size()); // 3
System.out.println(nameToNumbers.keySet().size()); // 2
*****************************************************************
Another nice choice is to use MultiValuedMap from Apache Commons. Take a look at
the
All Known Implementing Classes at the top of the page for specialized
implementations.
Example:
map.put(key, "A");
map.put(key, "B");
map.put(key, "C");
Just for the record, the pure JDK8 solution would be to use Map::compute method:
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);
}
with output:
bar: foo
first: hello, foo, hello
Note that to ensure consistency in case multiple threads access this data
structure, ConcurrentHashMap and CopyOnWriteArrayList for instance need to be used.