Java 8 流中的 LINQ Enumerable.Single() [重复]
Posted
技术标签:
【中文标题】Java 8 流中的 LINQ Enumerable.Single() [重复]【英文标题】:LINQs Enumerable.Single() in Java 8's Streams [duplicate] 【发布时间】:2015-05-07 03:22:53 【问题描述】:我对 C# 的 LINQ 有一些经验,并且正在尝试学习 Java 8 的流 API。现在在 LINQ 中,我经常使用 Single() Method,它从序列中挑选出唯一的对象,如果流中没有唯一的对象,则抛出异常。
现在:
我认为 Java 8 的流没有这样的方法是否正确? 是否有获得此功能的首选替代方法? 自己实现这个是个好主意吗?【问题讨论】:
确实有点回答我的问题 1) 方法不是开箱即用的 2) 很多选项,对于首选的内容没有共识,自定义收集器看起来不错 3) 实现自定义收集器是什么人们在建议。所以感谢链接,搜索它但显然不够好。我需要采取什么措施来确认这是重复的吗? 您还应该考虑 Brian Goetz 的答案(或者将其包装在一个简单的实用方法中);或使用 Guava Iterators 实用程序类;具有您正在寻找的Single
行为。 T elem = Iterators.getOnlyElement(stream.iterator());
stream.collect(Collectors.toMap(()->"single", Functions.identity()).get("single")
如果有多个元素,也会抛出...
【参考方案1】:
这是获得此功能的一种方法:
Stream<String> stream = Stream.of ("first");
String single = stream.reduce((a,b)->throw new SomeException();)
.get();
这个想法是,如果有多个元素,reduce
会在 lambda 表达式中抛出异常。如果没有元素,get()
将抛出 NoSuchElementException
。
您也可以通过将代码更改为:
来更改没有元素时抛出的异常:Stream<String> stream = Stream.of ("first");
String single = stream.reduce((a,b)->throw new SomeException();)
.orElseThrow(SomeException::new);
【讨论】:
为什么会这样:用于reduction 的associative 累积函数仅在有多个元素时才由流调用。如果有单个元素,则流解析为该元素。我们劫持此功能以引发异常而不是累积值。它既聪明又简洁,但可能会令人困惑,因为这不是 API 的预期用途。以上是关于Java 8 流中的 LINQ Enumerable.Single() [重复]的主要内容,如果未能解决你的问题,请参考以下文章