简体   繁体   中英

Get unique Object from a Stream if present

Starting with a bean class MyBean with a single relevant propterty:

@Data
class MyBean {
    private String myProperty;
}

Now I have got a set of these beans Set<MyBean> mySet usually with 0, 1, or 2 elements.

The question is: How do I retrieve myProperty from this set if it is equal for all elements, or else null. Preferably in a single line with effort O(n).

I found several examples to determine the boolean if all properties are equal. But I want to know the corresponding property.

Is there something smarter than this?

String uniqueProperty = mySet.stream().map(MyBean::getMyProperty).distinct().count() == 1 
    ? mySet.stream().map(MyBean::getMyProperty).findAny().orElse(null) 
    : null;

Your version is already O(n) .

It's possible to do this with a one-liner (although yours is too depending on how you write it).

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

The only case this doesn't work for is when all property values are null . You cannot distinguish the set (null, null) from (null, "A") for example, they both return null .

Just a single iteration without the use of streams looks much better for such a use case :

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;
    }
}

You use the findAny() first and check mySet again with allMatch() to require all items to match the first one in a filter() :

String uniqueProperty = mySet.stream().findAny().map(MyBean::getMyProperty)
        .filter(s -> mySet.stream().map(MyBean::getMyProperty).allMatch(s::equals))
        .orElse(null);

The advantage of this is, that allMatch() will only evaluate all elements if necessary ( docs ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM