当出现null时,如何使用Stream过滤Map?

时间:2017-06-23 17:16:30

标签: java dictionary nullpointerexception java-8 java-stream

我想通过Map过滤Stream中的一些值。让我们看一个简单的例子,我想用密钥提取条目,例如,高于2。

以下是我使用的代码:

Map<Integer, String> map = new HashMap<>(); 
map.put(1, "one"); 
map.put(2, "two"); 
map.put(3, "three"); 
map.put(4, "four"); 

Map<Integer, String> map2 = map.entrySet().stream()
    .filter(e -> e.getKey() > 2)
    .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()));

System.out.println(map2.toString());

结果正确:

  

{3 =三,四=四}

当我决定将字符串值设为null时,这是合法的,这是抛出的:

  

线程中的异常&#34; main&#34;显示java.lang.NullPointerException

以下是代码的延续:

map.put(5, null);
map.put(6, "six");

Map<Integer, String> map3 = map.entrySet().stream()
    .filter(e -> e.getKey() > 2)
    .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()));

System.out.println(map3.toString());

我期待结果:

  

{3 =三,四=四,五=空,6 =六}

好吧,当我将过滤器Predicate中的条件更改为e -> e.getKey() < 2时,它会起作用,因为null值不受影响。如何使用Stream处理此问题? null值可能会在任何地方故意发生。我不想使用for-loop。不应该Stream架构更多&#34;零安全&#34;?

问题How should we manage jdk8 stream for null values处理不同的问题。我不想使用.filter(Objects::nonNull),因为我需要保留null值。

请不要将其标记为与着名What is a NullPointerException and how do I fix it重复。我很清楚这一点,我问使用Stream的解决方案,这不像for-loop那样低级。这种行为限制了我。

1 个答案:

答案 0 :(得分:1)

可选是一个容器对象,用于包含非空对象。可选对象用于表示缺少值的null。

您可以这样做:

Map<Integer, Optional<String>> map = new HashMap<>(); 

//Optional.ofNullable - allows passed parameter to be null.
map.put(1, Optional.ofNullable("one")); 
map.put(2, Optional.ofNullable("two")); 
map.put(3, Optional.ofNullable(null)); 
map.put(4, Optional.ofNullable("four")); 

Map<Integer, Optional<String>> map2 = map.entrySet().stream()
        .filter(e -> e.getKey() > 2)
        .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()));

System.out.println(map2.toString());

<强>测试

{3=Optional.empty, 4=Optional[four]}

有关更多实用程序方法,以便于代码处理值可用不可用而不是检查null值,我建议您{{3 }}