在HashMap上添加到列表值

时间:2018-02-01 13:25:31

标签: java hashmap null-check

我正在填充一个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);

4 个答案:

答案 0 :(得分:7)

是的,Java 8中有:

List<Person> personsOfSameAge = myHashMap.computeIfAbsent(age,age->new ArrayList<Person>());
personsOfSameAge.add(person);

或者只是

myHashMap.computeIfAbsent(age,age->new ArrayList<Person>()).add(person);

答案 1 :(得分:7)

在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)); 的信息流可以缩短您的时间:

personsOfSameAge.add(person);

作为旁注,您的实际Java 7代码也可以得到改进。 当然,没有Java 8那么多,但如果你不能使用Java 8,这可能很有趣 在您的实际代码中,这是重复的:

if

你使用两个条件语句(elseif),如果你先处理特殊情况,只有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); } 中没有值。
这是一个修改版本:

def md5(fname):
   hash_md5 = hashlib.md5()
   with open(fname, "rb") as f:
       for chunk in iter(lambda: f.read(4096), b""):
           hash_md5.update(chunk)
   return base64.b64encode(hash_md5.digest()).decode('utf-8')

答案 2 :(得分:1)

这样的东西?

  List<Person> newList = Optional.ofNullable( myHashMap.get(age)).orElse(new ArrayList<>());
  newList.add(person);
  myHashMap.put(age, newList);

答案 3 :(得分:1)

虽然问题涉及在Java 8中进行,但我将其作为替代方式发布。

您可以使用MultiMap from Google Guava

Multimap<String, Person> myHashMap = ArrayListMultimap.create();
for (Person person : persons) {
   myHashMap.put(person.getAge(), person);
}

但是,您必须注意区别:当Google Guava的MultiMap返回null时,Java的地图会返回empty List以查找不存在的密钥。< / p>

从javadoc获取MultiMap的 get(key)

  

返回与此multimap中的key关联的值的视图集合(如果有)。请注意,当containsKey(key)为false时,返回空集合,而不是null。   对返回的集合的更改将更新基础多图,反之亦然