Collectors.toMap() 在内部给出 NPE



>我正在尝试在流执行中收集数据作为映射。

为了确保我没有任何重复项,我正在使用merger function但最终有 NPE。

查看代码片段

streamableList().stream()
.filter(Objects::nonNull)
.filter(it-> nonNull(it.getKeyHere()))
.collect(toMap(it -> it.getKeyHere(),
it -> it.getValueHere(), (a1, a2) -> a1));

请参阅下面的例外情况

java.lang.NullPointerException: null
at java.util.HashMap.merge(HashMap.java:1216)
at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320)
at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)....
.....and further calls of written code....

谁能建议为什么它在收集时失败以及如何解决?

如果任何值为 null,则HashMap::merge抛出。

@Override
public V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
if (value == null)
throw new NullPointerException(); //here

所以getValueHere必须返回null.您只对项目和键执行空检查,而不对值执行空检查。

您可以添加另一个筛选器,或确保您的类不包含 null 值。

.filter(it -> Objects.nonNull(it.getValueHere()))

Edit

我刚刚从Java 1.8中查找了HashMap代码。这是片段。当要合并的值作为null传递时,它会抛出一个 NPE。

@Override
public V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
if (value == null)
throw new NullPointerException();

原始帖子

是的,正如@Pshema指出的,当it.getValueHere()返回时null,我们得到这个错误。这是复制品。

public class NPECollectorsToMap{
public static void main( String[] args ){
Map<String, String> map = doThis();
System.out.println( map );
}
private static Map<String, String> doThis() {
return streamableList().stream()
.filter(Objects::nonNull)
.filter(it-> nonNull(it.getKeyHere()))
.collect(toMap(it -> it.getKeyHere(),
it -> it.getValueHere(), (a1, a2) -> a1));
}
private static List<It> streamableList(){
List<It> list = new ArrayList<>();
list.add( new It( "a", null ) );
return list;
}
private static class It{
private String keyHere;
public It( String keyHere, String valueHere ){
super();
this.keyHere = keyHere;
this.valueHere = valueHere;
}
private String valueHere;
public String getKeyHere(){ return keyHere; }
public void setKeyHere( String keyHere ){ this.keyHere = keyHere; }
public String getValueHere(){ return valueHere; }
public void setValueHere( String valueHere ){ this.valueHere = valueHere; }
}
}

最新更新