但是如果lambda的使用姿势不对,会造成意向不到的问题。下面就总结几个常见的Java lambda坑(不正确的使用姿势)~
Collectors.toMap报Duplicate key异常
首先看下以下代码:
// 将list转换成map接口
List<String> list = Arrays.asList("a", "b", "c", "a");
Map<String, String> map = list.stream().collect(Collectors.toMap(k -> k, v -> v));
System.out.println(map);直接执行代码会报异常:
Exception in thread "main" java.lang.IllegalStateException: Duplicate key a
at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)
at java.util.HashMap.merge(HashMap.java:1254)
at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320)
at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
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)这是为什么呢?因为默认情况下,也就是Collectors.toMap(k -> k, v -> v)未指定BinaryOperator<U> mergeFunction时,使用的mergeFunction为:
(u,v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); };这样在出现重复key时就会报异常了,所以,在开发中如果不能保证lambda的Collectors.toMap元素不重复,那么就需要自定义mergeFunction,可以将示例代码更改如下就可以了。
List<String> list = Arrays.asList("a", "b", "c", "a");
// v1表示old value,v2表示current value
Map<String, String> map = list.stream().collect(Collectors.toMap(k -> k, v -> v, (v1, v2) -> v1));
System.out.println(map);findFirst空指针异常
首先看下如下代码:
List<String> list = Arrays.asList("a", "b", "c");
String value = list.stream().map(o -> o.equals("a") ? null : o)
.findFirst().orElse(null);
System.out.println(value);以上代码执行会报空指针,异常信息如下:
Exception in thread "main" java.lang.NullPointerException
at java.util. s.requireNonNull( s.java:203)
at java.util.Optional.<init>(Optional.java:96)
at java.util.Optional.of(Optional.java:108)
at java.util.stream.FindOps$FindSink$OfRef.get(FindOps.java:193)
at java.util.stream.FindOps$FindSink$OfRef.get(FindOps.java:190)
at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:464)因为findFirst使用的是Optional.of,而Optional.of要求元素必须非null,所以会报空指针,上述代码很容易看出来,如果findFirst前置逻辑较复杂,可能会疏忽元素可能为null情况,因为最好在执行findFirst前加上一个filter( s::nonNull)的逻辑。
继续阅读与本文标签相同的文章
上一篇 :
myeclipse 配置堆内存
下一篇 :
避免死锁的方法
-
centos7 lvm管理 把/home空间转移给/
2026-05-26栏目: 教程
-
随笔 - debian8 配置 WIFI
2026-05-26栏目: 教程
-
MySQL数据安全的双1模式简介
2026-05-26栏目: 教程
-
在cygwin上运行apache2
2026-05-26栏目: 教程
-
记一次异常停机损坏了orientdb 导致nexus2无法启动
2026-05-26栏目: 教程
