Java 8中Collectors.toMap空指针异常源码解析
作者:十方
这篇文章主要为大家介绍了Java 8中Collectors.toMap空指针异常源码解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
引言
当需要将一个List转换为Map时,可以使用 Java 8 中的 Collectors.toMap()
方法,Map是由key-value组成的键值对集合,在使用Collectors.toMap()
方法时,如果值为空,会报空指针异常,下面通过一个实例来验证一下。
Student.java 类
首先定义一个 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 类创建
再创建一个 Test.java
类,用来验证将 List<Student> 转换为 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.NullPointerException at 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()
查看一下 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 异常
如果值为空,则会直接报出 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)); // 如果age为null,则直接赋值默认值0 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}
以上就是Java 8中Collectors.toMap空指针异常源码解析的详细内容,更多关于Java8 Collectors.toMap空指针异常的资料请关注脚本之家其它相关文章!
您可能感兴趣的文章:
- 基于java.lang.IllegalArgumentException异常报错问题及解决
- IDEA 中使用 ECJ 编译出现 java.lang.IllegalArgumentException的错误问题
- 如何解决Mybatis--java.lang.IllegalArgumentException: Result Maps collection already contains value for X
- java捕获AOP级别的异常并将其传递到Controller层
- java封装全局异常处理深入详解
- java.lang.IllegalArgumentException:Invalid character found异常解决