[英]Get unique Object from a Stream if present
从具有单个相关属性的bean类MyBean
开始:
@Data
class MyBean {
private String myProperty;
}
现在,我有了一组这些bean Set<MyBean> mySet
通常带有0、1或2个元素。
问题是:如果所有元素均相等,则如何从该集中检索myProperty
,否则为null。 优选地,在单线中具有努力O(n)。
我发现了几个确定所有属性是否相等的布尔值的示例。 但是我想知道相应的属性。
有比这更聪明的东西吗?
String uniqueProperty = mySet.stream().map(MyBean::getMyProperty).distinct().count() == 1
? mySet.stream().map(MyBean::getMyProperty).findAny().orElse(null)
: null;
您的版本已经是O(n)
。
可以使用单线执行此操作(尽管您也取决于编写方式)。
String uniqueProperty = mySet.stream()
.map(MyBean::getMyProperty)
.map(Optional::ofNullable)
.reduce((a, b) -> a.equals(b) ? a : Optional.empty()) // Note: equals compares 2 Optionals here
.get() // unwraps first Optional layer
.orElse(null); // unwraps second layer
唯一不起作用的情况是所有属性值均为null
。 例如,您无法将(null, null)
与(null, "A")
区分,它们都返回null
。
对于这样的用例,仅一次迭代而不使用流看起来更好:
Iterator<MyBean> iterator = mySet.iterator();
String uniqueProperty = iterator.next().getMyProperty();
while (iterator.hasNext()) {
if (!iterator.next().getMyProperty().equals(uniqueProperty)) {
uniqueProperty = null; // some default value possibly
break;
}
}
您首先使用findAny()
, mySet
再次使用allMatch()
检查mySet
,以要求所有项目都与filter()
中的第一个项目匹配:
String uniqueProperty = mySet.stream().findAny().map(MyBean::getMyProperty)
.filter(s -> mySet.stream().map(MyBean::getMyProperty).allMatch(s::equals))
.orElse(null);
这样做的好处是, allMatch()
仅在必要时评估所有元素( docs )。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.