【发布时间】:2017-11-27 08:25:54
【问题描述】:
我想通过Stream 过滤Map 中的一些值。让我们看一个简单的例子,我想提取带有键的条目,例如大于 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=三个,4=四个}
当我决定将String值设为null时,这是合法的,这是抛出:
线程“主”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=3, 4=4, 5=null, 6=6}
好吧,当我将过滤器的Predicate 中的条件更改为e -> e.getKey() < 2 时,它会起作用,因为null 值不受影响。如何使用Stream 处理这个问题? null 值可能有意出现在任何地方。我不想使用 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-loop 那样低级。这种行为非常限制我。
【问题讨论】:
-
@NikolasCharalambidis 与当前的
toMap实现你不能放空值。您必须创建自己的collector- 这在链接问题的答案之一中有所描述 -
@NikolasCharalambidis 链接的问题(连同他们的答案)怎么没有回答您的问题?
-
除非你没有告诉我们什么,否则它就是重复的。确切的答案是:
Map<Integer, String> map3 = map.entrySet().stream().filter(e -> e.getKey() > 2).collect(HashMap::new, (map, entry) -> map.put(entry.getKey(), entry.getValue()), HashMap::putAll);这能满足您的需求吗? -
因为 是 链接问题之一中的答案......但这应该没关系 - 你找到你的解决方案很好
标签: java dictionary nullpointerexception java-8 java-stream