1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Java 8中Collectors.toMap空指针异常源码分析

Java 8中Collectors.toMap空指针异常源码分析

时间:2019-07-26 12:00:14

相关推荐

Java 8中Collectors.toMap空指针异常源码分析

当需要将一个List转换为Map时,可以使用 Java 8 中的Collectors.toMap()方法,Map是由key-value组成的键值对集合,在使用Collectors.toMap()方法时,如果值为空,会报空指针异常,下面通过一个实例来验证一下。

首先定义一个Student.java

package com.magic.npe;public class Student {private String name;private Integer age;public Student(String name, Integer age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}}

再创建一个Test.java类,用来验证将 List 转换为 Map<String, Integer>。

package com.magic.npe;import java.util.ArrayList;import java.util.List;import java.util.Map;import java.util.stream.Collectors;public class Test {public static void main(String[] args) {List<Student> students = new ArrayList<>();students.add(new Student("张三", 18));students.add(new Student("李四", 21));students.add(new Student("王五", null));Map<String, Integer> studentMap = students.stream().collect(Collectors.toMap(Student::getName, Student::getAge));System.out.println(studentMap);}}

运行程序,直接报出如下的错误信息

Exception in thread "main" java.lang.NullPointerExceptionat java.util.HashMap.merge(HashMap.java:1224)at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320)at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)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)at com.magic.npe.Test.main(Test.java:16)

查看一下Collectors.toMap()方法的源码,如下:

public static <T, K, U>Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,Function<? super T, ? extends U> valueMapper,BinaryOperator<U> mergeFunction) {return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);}

默认会创建一个HashMap,继续查看源码:

public static <T, K, U, M extends Map<K, U>>Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,Function<? super T, ? extends U> valueMapper,BinaryOperator<U> mergeFunction,Supplier<M> mapSupplier) {BiConsumer<M, T> accumulator= (map, element) -> map.merge(keyMapper.apply(element),valueMapper.apply(element), mergeFunction);return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID);}

通过Map.merge()方法来合并,源码如下:

default V merge(K key, V value,BiFunction<? super V, ? super V, ? extends V> remappingFunction) {Objects.requireNonNull(remappingFunction);Objects.requireNonNull(value);V oldValue = get(key);V newValue = (oldValue == null) ? value :remappingFunction.apply(oldValue, value);if(newValue == null) {remove(key);} else {put(key, newValue);}return newValue;}

可以看到,在merge()方法中,要求value值不能为空

Objects.requireNonNull(value);

继续查看一下Objects.requireNonNull()方法的源码

public static <T> T requireNonNull(T obj) {if (obj == null)throw new NullPointerException();return obj;}

如果值为空,则会直接报出NullPointerException异常。

那么,对于这个空指针异常问题,如何解决呢?一般有两种方式:

(1)替换空值null为一个默认值,比如0

package com.magic.npe;import java.util.ArrayList;import java.util.List;import java.util.Map;import java.util.Optional;import java.util.stream.Collectors;public class Test {public static void main(String[] args) {List<Student> students = new ArrayList<>();students.add(new Student("张三", 18));students.add(new Student("李四", 21));students.add(new Student("王五", null));Map<String, Integer> studentMap = students.stream().collect(Collectors.toMap(Student::getName, s -> Optional.ofNullable(s.getAge()).orElse(0)));System.out.println(studentMap);}}

运行程序,输出结果如下:

{李四=21, 张三=18, 王五=0}

(2)调用collect()的其他实现方法

package com.magic.npe;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;public class Test {public static void main(String[] args) {List<Student> students = new ArrayList<>();students.add(new Student("张三", 18));students.add(new Student("李四", 21));students.add(new Student("王五", null));Map<String, Integer> studentMap = students.stream().collect(HashMap::new, (map, student) -> map.put(student.getName(), student.getAge()), HashMap::putAll);System.out.println(studentMap);}}

运行程序,输出结果如下:

{李四=21, 张三=18, 王五=null}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。