Collectors.groupingBy分组后返回list集合
时间: 2023-10-15 13:26:45 浏览: 122
Collectors.groupingBy默认情况下分组后返回的是HashMap类型的集合。通过修改为LinkedHashMap类型即可返回LinkedHashMap集合。这样可以保持分组后的顺序不发生乱序。<span class="em">1</span><span class="em">2</span><span class="em">3</span>
#### 引用[.reference_title]
- *1* *2* *3* [Collectors.groupingBy分组后乱序问题](https://blog.csdn.net/weixin_43883917/article/details/121502336)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"]
[ .reference_list ]
相关问题
Collectors.groupingBy value不返回list
Collectors.groupingBy是Java 8中的一个用于分组操作的工具类,它可以根据指定的条件将元素分组,并将分组结果存储在一个Map中。默认情况下,Collectors.groupingBy的value会返回一个List,其中包含属于同一组的所有元素。
然而,有时候我们可能希望对分组结果进行其他处理,而不是返回一个List。在这种情况下,我们可以使用Collectors.toSet()方法来替代默认的List,以获取不重复的元素集合。
下面是一个示例代码,演示了如何使用Collectors.groupingBy和Collectors.toSet来实现不返回List的分组操作:
```java
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class GroupingByExample {
public static void main(String[] args) {
List<String> fruits = Arrays.asList("apple", "banana", "orange", "apple", "banana");
// 使用Collectors.groupingBy和Collectors.toSet进行分组操作
Map<String, Set<String>> groupedFruits = fruits.stream()
.collect(Collectors.groupingBy(fruit -> fruit, Collectors.toSet()));
// 输出分组结果
for (Map.Entry<String, Set<String>> entry : groupedFruits.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
}
```
运行以上代码,输出结果如下:
```
orange: [orange]
banana: [banana]
apple: [apple]
```
可以看到,使用Collectors.toSet()替代默认的List,我们得到了不重复的元素集合作为分组结果。
Collectors.groupingBy 分组之后排序
### Java Stream Collectors GroupingBy 结果排序
当使用 `Collectors.groupingBy` 对数据进行分组后,可以通过多种方式对结果进行排序。一种常见的方式是在收集器链中加入额外的操作来实现这一点。
对于按照特定键值分组后的映射表(通常是 `Map<K,V>`),如果希望按键排序,则可以在创建流之前先对源列表进行预处理;而如果是想要基于某些计算出来的汇总值排序,则可在最终收集阶段指定自定义比较逻辑。
#### 按照键顺序排序的例子:
```java
import java.util.*;
import java.util.stream.Collectors;
class Employee {
private String name;
private int salary;
private String department;
// Constructor, getters and setters...
}
public class Main {
public static void main(String[] args) {
List<Employee> employees = Arrays.asList(
new Employee("Alice", 70_000, "HR"),
new Employee("Bob", 80_000, "Engineering"),
new Employee("Charlie", 90_000, "Marketing")
);
TreeMap<String, Long> sortedGroupedByDepartment =
employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment,
() -> new TreeMap<>(),
Collectors.counting()));
System.out.println(sortedGroupedByDepartment);
}
}
```
这段代码展示了如何通过提供一个有序的集合工厂方法给定初始容量为零的新实例作为第二个参数传递给 `groupingBy()` 来获得自然排序的结果[^1]。
#### 基于聚合函数返回值排序的方法:
另一种情况是当我们不仅关心分组依据本身还关注每组内部的数据特征时——比如总和、平均数等统计量。此时可以利用复合型收集器完成更复杂的任务,并且在最后一步应用 `toMap()` 或者其他形式的终端操作来自定义输出格式及其排列规则。
下面是一个例子说明怎样根据部门内员工薪资总额降序展示各个团队的信息:
```java
employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment))
.entrySet().stream()
.sorted(Map.Entry.<String, List<Employee>>comparingByKey())
.map(entry -> entry.getKey() +
": Total Salary=" +
entry.getValue().stream()
.mapToInt(Employee::getSalary).sum())
.forEach(System.out::println);
```
这里先是进行了简单的分组,接着转换成条目集以便能够对其进行进一步加工,再调用 `sorted()` 方法并传入合适的比较器以决定元素间的相对位置关系,最后经过一系列中间运算得出所需信息并打印出来[^2]。
为了简化上述过程中的部分步骤以及提高可读性和灵活性,在实际开发过程中还可以考虑采用如下所示的一次性解决方案:
```java
employees.stream()
.collect(Collectors.toMap(
Employee::getDepartment,
e -> Collections.singletonList(e),
(e1, e2) -> {
ArrayList<Employee> combined = new ArrayList<>(e1);
combined.addAll(e2);
return combined; },
LinkedHashMap::new)) // Keep insertion order or use another supplier like TreeMap for natural ordering.
.entrySet().stream()
.sorted((a,b)->Long.compare(b.getValue().stream().mapToInt(Employee::getSalary).sum(),
a.getValue().stream().mapToInt(Employee::getSalary).sum()))
.forEachOrdered(entry->System.out.printf("%s : %d\n",
entry.getKey(),
entry.getValue().stream().mapToInt(Employee::getSalary).sum()));
```
此片段实现了相同的功能但是更加紧凑直观一些[^3]。
阅读全文