Java 8:从 HashMap 获取默认值并更新底层映射

Ste*_*son 5 java hashmap java-8

我正在寻找为HashMapget 操作提供默认值的最佳方法(可读性和效率),但如果值尚不存在,还要使用该默认值更新底层映射。

我知道那里有 3rd 方库,但我更愿意坚持使用标准 Java。以下是我想到的一些不同的方法:

老套

Map<String, List<Integer>> someIntegerListLookup = new HashMap<>();
String key = "key";
...
List<Integer> integerList = someIntegerListLookup.get(key);

if (integerList == null) {
    integerList = new ArrayList<>();
    someIntegerListLookup.put(key, integerList);
}
Run Code Online (Sandbox Code Playgroud)

Java 8 Map 方法

// getOrDefault
List<Integer> integerList = someIntegerListLookup.getOrDefault(key, new ArrayList<>());
someIntegerListLookup.put(key, integerList);

// putIfAbsent
someIntegerListLookup.putIfAbsent(key, new ArrayList<>());
List<Integer> integerList = someIntegerListLookup.get(key);
Run Code Online (Sandbox Code Playgroud)

使用 Java 8 可选

List<Integer> integerList = 
    Optional.ofNullable(someIntegerListLookup.putIfAbsent(key, new ArrayList<>()))
    .orElse(someIntegerListLookup.get(key));
Run Code Online (Sandbox Code Playgroud)

从可读性的角度来看,不喜欢这种方法。

使用“或其他”供应商:

List<Integer> integerList = Optional.ofNullable(someIntegerListLookup.get(key))
    .orElseGet(() -> {
        // Only runs if the map contains no value for the key
        List<Integer> defaultIntegersList = new ArrayList<>();
        someIntegerListLookup.put(key, defaultIntegersList);
        return defaultIntegersList;
    });
Run Code Online (Sandbox Code Playgroud)

现在我倾向于上述解决方案是最好的选择。是否有其他(更好的)解决方案是我没有想到或遇到的?

Era*_*ran 5

ArrayList如果密钥存在,您不想不必要地创建新的。

因此使用:

List<Integer> integerList = someIntegerListLookup.computeIfAbsent(key, s -> new ArrayList<>());
Run Code Online (Sandbox Code Playgroud)


Mur*_*nik 5

computeIfAbsent方法正是为此目的而设计的:

List<Integer> value = 
    someIntegerListLookup.computeIfAbsent("a", x -> new ArrayList<>());
Run Code Online (Sandbox Code Playgroud)

  • @Andreas 这是错误的。映射函数参数将键作为参数。由于 `ArrayList` 没有来自 `String` 的构造函数,所以在这里使用 `ArrayList::new` 是不合适的。您必须使用 lambda 或类似的东西。 (3认同)