我正在填充一个hashmap,让我的对象按其属性之一进行分组。我发现在将对象添加到列表之前检查列表(值)是否存在“丑陋”。
一个例子将更明确:
// 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);
}
}
有没有更好的方法来编码?
myHashMap.addToValueListOrCreateValueList(myObject);
在Java 8中,您的整个代码可以像这样编写(如提出的其他精细答案):
Map<Integer, List<Person>> myHashMap = new HashMap();
for (Person person : persons) {
myHashMap.computeIfAbsent(age,age->new ArrayList<Person>()).add(person);
}
但是通过使用与Map
收集到Collectors.groupingBy()
的流可以更短:
Map<Integer, List<Person>> myMap = persons.stream().collect(Collectors.groupingBy(Person:getAge));
作为旁注,您的实际Java 7代码也可以得到改进。当然,没有Java 8那么多,但如果你不能使用Java 8,这可能会很有趣。 在您的实际代码中,这是重复的:
personsOfSameAge.add(person);
并且你使用两个条件语句(if
和else
),而如果你先处理特殊情况,只有if
就足够了:Map
中没有值。
这是一个修改版本:
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);
}
是的,Java 8中有:
List<Person> personsOfSameAge = myHashMap.computeIfAbsent(age,age->new ArrayList<Person>());
personsOfSameAge.add(person);
要不就
myHashMap.computeIfAbsent(age,age->new ArrayList<Person>()).add(person);
像这样的东西?
List<Person> newList = Optional.ofNullable( myHashMap.get(age)).orElse(new ArrayList<>());
newList.add(person);
myHashMap.put(age, newList);
虽然问题涉及在Java 8中进行,但我将其作为替代方式发布。
你可以使用MultiMap from Google Guava。
Multimap<String, Person> myHashMap = ArrayListMultimap.create();
for (Person person : persons) {
myHashMap.put(person.getAge(), person);
}
但是,你必须意识到一个区别:Java的地图返回null
表示不存在的键,而Google Guava的MultiMap返回empty List
。
从javadoc获取MultiMap的get(key)
返回与此多图中的键关联的值的视图集合(如果有)。请注意,当containsKey(key)为false时,返回空集合,而不是null。对返回的集合的更改将更新基础多图,反之亦然