I have the following Student
object:
public class Student {
private String gradeAndClass;
private String gender;
private String name;
// getters, constructor, etc.
}
In the original code, properties gradeAndClass and gender are enums, but for the purpose of simplicity let's consider them to be strings.
I have a map Map<String,Student>
, where key is a unique string and value is a Student
object.
I need this map to split into a bunch of maps Map<String,Student>
, so the result should be a list of submaps List<Map<String,Student>>
.
Let's consider the following example:
Map<String, Student> data = new HashMap<>();
data.put("key1", new Student("class_1", "Boy", "Jo"));
data.put("key2", new Student("class_2", "Girl", "Alice"));
data.put("key3", new Student("class_1", "Girl", "Amy"));
data.put("key4", new Student("class_2", "Girl", "May"));
data.put("key5", new Student("class_1", "Boy", "Oscar"));
data.put("key6", new Student("class_2", "Boy", "Jimmy"));
data.put("key7", new Student("illegal class name", "Boy", "err1"));
data.put("key8", new Student("class_2", "not supported", "err2"));
Is there an easy way to split the Map
first by gradeAndClass
then by gender
, so that the result would be a list containing the following submaps:
- Submap 1:
"key1", ["class_1", "Boy", "Jo"]
"key5", ["class_1", "Boy", "Oscar"]
- Submap 2:
"key3", ["class_1", "Girl", "Amy"]
- Submap 3:
"key6", ["class_2", "Boy", "Jimmy"]
- Submap 4:
"key2", ["class_2", "Girl", "Alice"]
"key4", ["class_2", "Girl", "May"]
Also, I'd like to aggregate the illegal inputs to a separate map:
- Submap 5:
"key7", ["illegal class name", "boy", "err1"]
"key8", ["class_2", "not supported", "err2"]
I tried to filter data related to each submap separately (making use of the fact gradeAndClass
and gender
in the original code are well-defined enums), but it is very inefficient.
Basically, I've hard-coded all the condition checks and had to filter and regroup by each gradeAndClass
and gender
. I also had to reiterate each entry to get the illegal entries in order to put them to a separate "error map".
Sorry, I am very new to streams, so I know my solution is definitely not scalable, and thus I am looking for suggestion. Would it be possible to use stream groupingBy()
to do all these?
Here's the code I've used to generate a separate submap:
Map<String, Student> submap = data.entrySet().stream()
.filter(entry -> "class_1".equals(entry.getValue()) &&
(other conditions))
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue
));