【发布时间】:2015-01-04 18:48:40
【问题描述】:
我对函数式编程和流的东西有点陌生,但我所知道的一点点却非常有用!
这种情况我遇到过好几次了:
List<SomeProperty> distinctProperties = someList.stream()
.map(obj -> obj.getSomeProperty())
.distinct()
.collect(Collectors.toList());
if (distinctProperties.size() == 1) {
SomeProperty commonProperty = distinctProperties.get(0);
// take some action knowing that all share this common property
}
我真正想要的是:
Optional<SomeProperty> universalCommonProperty = someList.stream()
.map(obj -> obj.getSomeProperty())
.distinct()
.collect(Collectors.singleOrEmpty());
我认为singleOrEmpty 除了与distinct 结合使用之外,在其他情况下也很有用。当我还是一个 uber n00b 时,我花了很多时间重新发明 Java 集合框架,因为我不知道它在那里,所以我尽量不重复我的错误。 Java 是否有一个很好的方法来做这件事singleOrEmpty?我是不是写错了?
谢谢!
编辑:这是distinct 案例的一些示例数据。如果忽略map 步骤:
Optional<SomeProperty> universalCommonProperty = someList.stream()
.map(obj -> obj.getSomeProperty())
.distinct()
.collect(Collectors.singleOrEmpty());
[] -> Optional.empty()
[1] -> Optional.of(1)
[1, 1] -> Optional.of(1)
[2, 2] -> Optional.of(2)
[1, 2] -> Optional.empty()
当我搞砸我的类型或有遗留代码时,我发现我需要这个。能够快速说出“这个集合的所有元素都共享这个属性,所以现在我可以使用这个共享属性执行一些操作”真是太好了。另一个例子是当用户多选一些不同的元素时,你试图看看你能做什么(如果有的话)对所有元素都有效。
EDIT2:抱歉,如果我的示例具有误导性。关键是singleOrEmpty。我通常发现我在前面放了一个distinct,但它也可以很容易地成为其他类型的filter。
Optional<SomeProperty> loneSpecialItem = someList.stream()
.filter(obj -> obj.isSpecial())
.collect(Collectors.singleOrEmpty());
[special] -> Optional.of(special)
[special, special] -> Optional.empty()
[not] -> Optional.empty()
[not, special] -> Optional.of(special)
[not, special, not] -> Optional.of(special)
EDIT3:我认为我通过激励 singleOrEmpty 而不是仅仅要求它自己搞砸了。
Optional<Int> value = someList.stream().collect(Collectors.singleOrEmpty())
[] -> Optional.empty()
[1] -> Optional.of(1)
[1, 1] -> Optional.empty()
【问题讨论】:
-
@Ned Twigg 你能好心点并发布你的 somelist 内容以便重现你的问题吗?
-
值得一提的是,在 C# 的 LINQ 中,这类似于
SingleOrDefault。
标签: java java-8 java-stream