4 回答

TA貢獻1799條經驗 獲得超8個贊
首先創建一個TreeMap
,其鍵是工資。TreeMap
按其鍵對其條目進行排序。然后獲取第一個條目,即工資最低的條目,并獲取與之相關的值。該解決方案僅迭代列表一次。它看起來是這樣的。
List<Employee>?empsWithLowestSalary?=?employees.stream() ????.collect(Collectors.groupingBy(Employee::getSalary,?TreeMap::new,?Collectors.toList())) ????.firstEntry() ????.getValue();
TreeMap
將地圖元素存儲在紅黑樹中。紅黑樹中一個元素的插入成本為O(Log (n))
。由于我們要插入n
元素,因此該解決方案的總時間復雜度為O(n Log (n))
。對于firstEntry()
,它需要恒定的時間O(1)
,因為它分別維護一個指向樹中最左邊和最右邊葉節點的指針。最左邊的節點代表樹中的最小值,而最右邊的葉節點代表樹中的最高值。
我想到編寫一個服務于我們目的的自定義收集器。該收集器僅對 List 進行迭代一次,其運行時復雜度為 O(n),這明顯優于上述方法。此外,它允許您在一條語句中編寫客戶端代碼。它看起來是這樣的。
static <T> Collector<T, ?, List<T>> minList(Comparator<? super T> comp) {
? ? return Collector.of(ArrayList::new, (list, t) -> {
? ? ? ? int c;
? ? ? ? if (list.isEmpty() || (c = comp.compare(t, list.get(0))) == 0)
? ? ? ? ? ? list.add(t);
? ? ? ? else if (c < 0) {
? ? ? ? ? ? /*
? ? ? ? ? ? ?* We have found a smaller element than what we already have. Clear the list and
? ? ? ? ? ? ?* add this smallest element to it.
? ? ? ? ? ? ?*/
? ? ? ? ? ? list.clear();
? ? ? ? ? ? list.add(t);
? ? ? ? }
? ? }, (list1, list2) -> {
? ? ? ? if (comp.compare(list1.get(0), list2.get(0)) < 0)
? ? ? ? ? ? return list1;
? ? ? ? else if (comp.compare(list1.get(0), list2.get(0)) > 0)
? ? ? ? ? ? return list2;
? ? ? ? else {
? ? ? ? ? ? list1.addAll(list2);
? ? ? ? ? ? return list1;
? ? ? ? }
? ? });
}
這是您的客戶端代碼。
Collection<Employee> empsWithLowestSalary = employees.stream()
? ? ? ? ? ? ? ? .collect(minList(Comparator.comparing(Employee::getSalary)));

TA貢獻1796條經驗 獲得超7個贊
Integer lowestSalary = employees.stream() .min(Comparator.comparing(Employee::getSalary)) .map(Employee::getSalary).get(); List<Employee> employeesWithLowestSalary = employees.stream() .filter(e -> e.getSalary() == lowestSalary) .collect(Collectors.toList());
首先查找最低工資是多少,然后過濾員工列表,以便只包含工資匹配的員工。

TA貢獻1777條經驗 獲得超10個贊
您可以按工資分組,然后檢索最低工資的員工列表:
List<Employee> employees = new ArrayList<Employee>(){{
add(new Employee("bilbo baggins", 10));
add(new Employee("frodo baggins", 10));
add(new Employee("gandalf grey", 100));
}};
Map<Integer, List<Employee>> result = employees.stream().collect(groupingBy(Employee::getSalary));
List<Employee> allMin = result.entrySet().stream()
.min(Comparator.comparing(Map.Entry::getKey))
.map(Map.Entry::getValue)
.orElse(Collections.emptyList());
allMin.forEach(System.out::println);
輸出
Employee{name='bilbo baggins', salary=10}
Employee{name='frodo baggins', salary=10}

TA貢獻1884條經驗 獲得超4個贊
您可以先計算最低工資,然后根據您的情況使用Stream#filter:
int salary =
employees.stream()
.min(Comparator.comparing(Employee::getSalary))
.map(e -> e.getSalary())
.orElse(-1);
List<Employee> emps =
employees.stream()
.filter(emp -> emp.getSalary() == salary)
.collect(Collectors.toList());
添加回答
舉報