簡體   English   中英

Java流API - 避免使用相同的謂詞兩次來計算平均值

[英]Java stream API - avoid using same predicate twice to calculate average

class A {
    double value;
    String key;
}

class B {
    List<A> aList;
}

給定List<B> bList ,我想計算特定密鑰kvalue s的平均值。 假設每個B只能用key.equals(k)保持A的實例的0或1倍。

我想我可以先過濾aList ,然后使用mapToDouble提取值:

double average = blist.stream().filter(
    b -> b.aList.stream().anyMatch(
        a -> a.key.equals(k)
    )
).mapToDouble(
    b -> b.aList.stream().filter(
        a -> a.key.equals(k)
    ).findFirst().get().value
).average().orElse(0);

但是這里顯然有一個冗余,因為我用相同的謂詞過濾相同的列表兩次( a -> a.key.equals(k) )。

有沒有辦法mapToDouble同時省略缺少匹配key s的元素?

編輯:

這是一個更具體的例子,希望它更容易理解:

String courseName;

...

double average = students.stream().filter(
    student -> student.getGrades().stream().anyMatch(
        grade -> grade.getCourseName().equals(courseName)
    )
).mapToDouble(
    student -> student.getGrades().stream().filter(
        grade -> grade.getCourseName().equals(courseName)
    ).findFirst().get().getValue()
).average().orElse(0);

System.out.println(courseName + " average: " + average);

嘗試這個:

double average = bList.stream()
        .flatMap(b -> b.aList.stream())
        .filter(a -> a.key.equals(k))
        .mapToDouble(a -> a.value)
        .average()
        .orElse(Double.NaN);

如果你的對象有私有字段和getter,他們真的應該這樣,它就像這樣:

double average = bList.stream()
        .map(B::getaList)
        .flatMap(List::stream)
        .filter(a -> a.getKey().equals(k))
        .mapToDouble(A::getValue)
        .average()
        .orElse(Double.NaN);

嘗試這個。

double average = blist.stream()
    .map(b -> b.aList.stream()
        .filter(a -> a.key.equals(k))
        .findFirst())
    .filter(a -> a.isPresent())
    .mapToDouble(a -> a.get().value)
    .average().orElse(0);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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