Map.contains与Map.values()。stream()。filter.find

时间:2018-07-19 16:36:51

标签: java java-8 stream java-stream optional

从Java 8开始,与检查Map是否包含元素有关的最佳实践是什么?我想检查Map是否包含一个元素,并基于该元素获取对象或创建一个新元素并将其放入地图中。功能上的方法似乎太冗长了。

final private static Map<Integer, BowlingBall> pool = new HashMap<>();
int number = 8;

必要的方法:

BowlingBall ballImperative = null;

if (pool.containsKey(number)) {
    ballImperative = pool.get(number);
} else {
    ballImperative = new BowlingBall(number);
    pool.put(number, ballImperative);
}

功能方式:

BowlingBall ballFunctional = pool.values().stream()
    .filter(k -> k.getNumber() == number)
    .findAny()
    .orElseGet(() -> new BowlingBall(number));

pool.put(number, ballFunctional);

4 个答案:

答案 0 :(得分:4)

["A1" "B1, B2" 10 "E1" "F1"]
["A1" "B1, B2" 10 "E2" "F1"]
["A1" "B3, B4" 20 "E2" "F1"]
["A1" "B3, B4" 20 "E1" "F1"]

容易得多。

答案 1 :(得分:3)

从Java 8开始,有两种新方法可用于此目的:

Map#putIfAbsent

Map<String, String> map = new HashMap<>();
map.put("hello", "world");
map.putIfAbsent("hello", "Luiggi");
System.out.println(map.get("hello"));

Map#computeIfAbsent

Map<String, String> map = new HashMap<>();
map.put("hello", "world");
map.computeIfAbsent("hello", s -> "Luiggi");
System.out.println(map.get("hello"));

它们之间的主要区别在于,前者在检查键是否已包含值之前先评估要放置的值。后者可以理解为懒集。示例:

public String createValue(String s) {
    System.out.println("value of s: " + s);
    return "hello " + s;
}


Map<String, String> map = new HashMap<>();
map.put("hello", "world");
//executing the line below will fire System.out.println from the method
map.putIfAbsent("hello", createValue("world"));
//executing the line below will not fire System.out.println from the method
map.computeIfAbsent("hello", s -> createValue("world"));
System.out.println(map.get("hello"));

根据您的情况,代码可以简化为:

pool.put(number, number -> new BowlingBall(number));

答案 2 :(得分:3)

还有更多方法:

  1. Map::putIfAbsent

    此处发生Map::putIfAbsent(K key, V value),而不是 流,计算值,并将键与键放到地图上(如果键 不存在。

    map.putIfAbsent(1, new BollwingBall(number));
    
  2. Map::computeIfAbsent

    另一种方法是Map::computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction),它使用映射函数来计算 关键的价值。按照与上述方法相同的原理进行工作。

    map.putIfAbsent(1, integer -> new BowlingBall(integer)); // the value is computed 
                                                             // from the key
    map.putIfAbsent(1, BowlingBall::new);                    // the shortened version of 
                                                             // the one above
    

答案 3 :(得分:2)

使用Map.computeIfAbsent()

来自文档:

  

如果指定的键尚未与某个值关联(或已映射为null),则尝试使用给定的映射函数计算其值,除非为null,否则将其输入到此映射中。

例如:

BowlingBall ballImperative = 
          pool.computeIfAbsent(number, BowlingBall::new);