簡體   English   中英

從流中獲取唯一對象(如果存在)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM