簡體   English   中英

Java Stream - maxBy - 如何找到平均工資最高的部門 Java 8

[英]Java Stream - maxBy - How to find a department with the highest Average salary with Java 8

我有一個Employee列表。

public class Employee {
    private String department;
    private double salary;
    // other properties
}

我正在嘗試找到平均工資最高的部門的名稱。

我試過的代碼:

List<Employee> employeeList = new ArrayList<Employee>();
employeeList.add(new Employee("abc", 38, "M", "QA", 115000.00d, 2016));
employeeList.add(new Employee("def", 23, "M", "Sports", 5000000.00d, 2011));
employeeList.add(new Employee("ghi", 38, "M", "QA", 120000.00d, 2007));
employeeList.add(new Employee("jkl", 35, "M", "DEV", 50000.00d, 2016));
employeeList.add(new Employee("mno", 30, "F", "QA", 80000.00d, 206));
employeeList.add(new Employee("pqr", 32, "F", "DEV", 75000.00d, 2014));

Map<String, Double> highestAvgSalary = employeeList.stream()
    .collect(Collectors.groupingBy(
        emp -> emp.getDepartment(),
        Collectors.averagingDouble(emp -> emp.getSalary(),                        
            Collectors.maxBy(Comparator.comparingDouble(emp -> emp.getSalary()))

代碼的最后一行觸發了編譯錯誤。 我如何必須申請maxBy()才能獲得部門的最高平均工資?

Collectors.averagingDouble()只需要一個參數 - 一個function將 stream 元素轉換為Double 傳遞下游收集器的嘗試是不正確的。

正如評論中提到的@Sayan Bhattacharya所說,這項任務無法在員工集合的單次迭代中完成。

我們需要在中間Map的 map 條目上創建一個 stream ,將 debarment-name 與其平均工資相關聯並對其應用max()操作。

Map.Entry<String, Double> highestAvgSalary = employeeList.stream()
    .collect(Collectors.groupingBy(
        Employee::getDepartment,
        Collectors.averagingDouble(Employee::getSalary)
    ))
    .entrySet().stream()
    .max(Map.Entry.comparingByValue())
    .get();

請注意max()產生一個Optional 可選的 API 提供了不同的方法來從中提取結果。 方法get()可能會產生NoSuchElementException ,以防空可選。 如果您對該案例有自定義例外 - 將其替換為orElseThrow(Supplier) 由於 Java 10 根據文檔get()不鼓勵使用(除非您不確定結果是否存在),推薦的做法是使用orElseThrow()的無參數風格。 顯然,您不能與Java 8一起使用,僅出於這個原因,我在上面的代碼中應用了get() (對於較低版本,避免冗長是有道理的)。 但是您仍然有其他選擇,例如orElse()orElseGet()

另請注意,將Map作為結果類型並不是很方便,因為您事先不知道薪水最高的部門的名稱(這將是 map 中包含的唯一條目的鍵)。 因此,您無法以方便的方式訪問此類 map 中的信息。 但是如果出於某種原因你真的需要一個單條目映射,那么你可以應用map(Map::ofEntries).get()而不是上面代碼中的get() ,它會給你Map<String, Double>結果。

暫無
暫無

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

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