Reputation: 1541
Is there a way to create multiple maps from a list in Java 8 using stream or other way?
I have a list of custom object. Suppose List where Employee has departmentId so there are some employees which have the same departmentId = "001" for example. I want to create multiple maps based on Employee.departmentId.
For example,
map1 = <"001", employee1>,<"001", employee3>, <"001", employee8>...<"001", employee100>
map2 = <"002", employee2>,<"002", employee4>,..., <"002", employee8> ... something like this.
since for each element in list check the departmentId and put it in corresponding map by using old for loop. Wondering is there a better way to do this? Currently I'm using Java 8
Upvotes: 4
Views: 3082
Reputation: 40057
As has been suggested, using a Map<String,List<Employee>>
is probably what you want. I constructed a small class and an example to illustrate the process.
List<Employee> emps = List.of(
new Employee("001", "Jim"),
new Employee("002", "Bob"),
new Employee("001", "June"),
new Employee("002", "Jean"));
// For each employee, using departmentId as the key, construct
// a map containing lists of all employees that have that ID
Map<String, List<Employee>> empMap =
emps
.stream()
.collect(
Collectors.groupingBy(emp -> emp.departmentId)
);
for (Entry<?, ?> e : empMap.entrySet()) {
System.out.println(e.getKey() + "-->" + e.getValue());
}
class Employee {
public String departmentId;
public String name;
public Employee(String departmentId, String name) {
this.departmentId = departmentId;
this.name = name;
}
public String toString() {
return "(" + departmentId + " " + name + ")";
}
}
This displays
001-->[(001 Jim), (001 June)]
002-->[(002 Bob), (002 Jean)]
Another option, which would do the exact same thing is as follows:
This creates an empty map. Then it iterates over the list of employees and computes whether the value for the key exists. If it does, it returns the list and adds the entry to that list. If it doesn't, it then creates the new ArrayList and then adds the employee for that list, storing the list in the provided key.
Map<String, List<Employee>> emp2 = new HashMap<>();
for (Employee emp : emps) {
emp2.compute(emp.departmentId,
(ID, list) -> list == null ? new ArrayList<>()
: list).add(emp);
}
In this case my preference would be the first method.
Upvotes: 3
Reputation: 1332
none of the existing Java core Map implementations allow a Map to handle multiple values for a single key.
if we try to insert two values for the same key, the second value will be stored, while the first one will be dropped.
Map<String, String> map = new HashMap<>();
assertThat(map.put("key1", "value1")).isEqualTo(null);
assertThat(map.put("key1", "value2")).isEqualTo("value1");
assertThat(map.get("key1")).isEqualTo("value2");
you can achieve what you want by using Collection as Value here is a simple example :
using java version < 8
Map<String, List<String>> map = new HashMap<>();
List<String> list = new ArrayList<>();
map.put("key1", list);
map.get("key1").add("value1");
map.get("key1").add("value2");
assertThat(map.get("key1").get(0)).isEqualTo("value1");
assertThat(map.get("key1").get(1)).isEqualTo("value2");
using java version > 8
Map<String, List<String>> map = new HashMap<>();
map.computeIfAbsent("key1", k -> new ArrayList<>()).add("value1");
map.computeIfAbsent("key1", k -> new ArrayList<>()).add("value2");
assertThat(map.get("key1").get(0)).isEqualTo("value1");
assertThat(map.get("key1").get(1)).isEqualTo("value2");
what you want exactly you can achieve it by using Apache Library !
Solution : add Maven or jar
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.1</version>
</dependency>
then :
MultiValuedMap<String, Employe> map = new ArrayListValuedHashMap<>();
map.put("key1", new Employe("blahblah"));
map.put("key1", new Employe("blahblah"));
map.put("key1", new Employe("blahblah"));
Other alternatives libraries : Guava Multimap
Link : https://guava.dev/releases/23.0/api/docs/com/google/common/collect/Multimap.html
Upvotes: 0
Reputation: 362
It is not possible to do this. Because Map
can not have duplicate key
.
You can create Map<String,List<Employee>>
by using Collectors.groupingBy()
Upvotes: 0