我想过滤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=three, 4=four}
当我决定将字符串值设置为 null
时,这是合法的,这是抛出的:
Exception in thread "main" 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=three, 4=four, 5=null, 6=six}
嗯,当我更改过滤器的 Predicate
中的条件时,它就起作用了。至e -> e.getKey() < 2
自 null
值不受影响。如何用 Stream
处理这个问题? null
值(value)可能有意出现在任何地方。我不想使用 for 循环。不应该Stream
架构更加“空安全”吗?
问题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 循环那么低级。这种行为相当限制我。
最佳答案
可选的是一个容器对象,用于包含非空对象。可选对象用于表示没有值的 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
值,我建议您引用documentation .
关于java - 当出现null时如何用Stream过滤Map?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44726813/