I'm populating a hashmap to have my objects grouped by one of their attributes. I find it “ugly” to check whether the list (the value) exists before adding my object to it.
An example will be more explicit:
// Need a map to group Person by age.
// Person = {age: int}
Map<Integer, List<Person>> myHashMap = new HashMap();
for (Person person : persons) {
int age = person.getAge();
List<Person> personsOfSameAge = myHashMap.get(age);
if (personsOfSameAge != null) {
personsOfSameAge.add(person);
} else {
personsOfSameAge = new ArrayList();
personsOfSameAge.add(person);
myHashMap.put(age, personsOfSameAge);
}
}
Is there a better way to code this?
myHashMap.addToValueListOrCreateValueList(myObject);
In Java 8, your whole code could be written like that (as other fine answers proposed):
Map<Integer, List<Person>> myHashMap = new HashMap();
for (Person person : persons) {
myHashMap.computeIfAbsent(age,age->new ArrayList<Person>()).add(person);
}
But you could be even shorter by using a stream that collects into a Map
with Collectors.groupingBy()
:
Map<Integer, List<Person>> myMap = persons.stream().collect(Collectors.groupingBy(Person:getAge));
As a side note, your actual Java 7 code could also be improved.
Of course, not as much as with Java 8 but if you cannot use Java 8, this may be interesting.
In your actual code, this is duplicated :
personsOfSameAge.add(person);
And you use two conditional statements (if
and else
) while only if
would be enough if you handle first the special case : no value in the Map
.
Here is a modified version :
Map<Integer, List<Person>> myHashMap = new HashMap<>();
for (Person person : persons) {
int age = person.getAge();
List<Person> personsOfSameAge = myHashMap.get(age);
if (personsOfSameAge == null) {
personsOfSameAge = new ArrayList();
myHashMap.put(age, personsOfSameAge);
}
personsOfSameAge.add(person);
}