java - Java从流中创建具有重复元素的多个列表
问题描述
我正在尝试获取一个列表并返回一个Map<String, List<String>
包含原始列表某些方面的列表,其中原始元素可能使用流作为不同键下的值多次出现。例如:
class Employee {
String firstName;
String lastName;
Status status;
}
enum Status {
FULL_TIME,
PART_TIME
}
List<Employee> employees = List.of(
new Employee("f1", "l1", Status.PART_TIME),
new Employee("f2", "l2", Status.FULL_TIME),
new Employee("f3", "l3", Status.PART_TIME),
new Employee("f4", "l4", Status.FULL_TIME));
生成的映射应具有如下键,并且列表必须是不可变的:
fName: ["f1", "f2", "f3", "f4"],
lName: ["l1", "l2", "l3", "l4"],
fullTime: ["f2 l2", "f4 l4"]
这对于多个流来说很容易,但是原始数据非常大,所以我试图一次性完成。如果有另一种我不知道的方法,我也可以使用 Guava 和 Apache Commons。谢谢!
编辑1:展示我现在的表现
这是我在三个流中所做的事情,我想简化为一个:
var firstName = employees.stream()
.map(e -> e.getFirstName())
.collect(Collectors.toUnmodifiableList());
var lastName = employees.stream()
.map(e -> e.getLastName())
.collect(Collectors.toUnmodifiableList());
var fullTime = employees.stream()
.filter(e -> e.getStatus().equals(Status.FULL_TIME))
.collect(Collectors.toUnmodifiableList());
解决方案
您可以将员工对象转换为对列表,其中对键是映射键,对值是列表的单个值。然后您可以通过键“分组”对。
Map<String, List<String>> vals = employees.stream()
.map(e -> Arrays.asList(
Pair.of("fname", e.firstName),
Pair.of("lname", e.lastName),
e.status == Status.FULL_TIME ? Pair.of("fullTime", e.firstName + " " + e.lastName) : null
))
.flatMap(Collection::stream)
.filter(Objects::nonNull)
.collect(Collectors.groupingBy(p -> p.getLeft(),
Collectors.mapping(p -> p.getRight(), Collectors.toUnmodifiableList())));
但是,此解决方案的内存消耗比我之前的答案中的要差,特别是在处理大流时。
推荐阅读
- google-sheets - 谷歌表格中的过滤器和查询
- vb.net - 如何删除datagrid wpf vb.net的重复复选框
- php - 为什么如果我向服务器上的数据库请求超过 100 行,但结果却一无所获?
- python - Python BigQuery - 更快或异步插入行
- python - Pyinstaller 应用程序:在系统启动时运行的文件夹创建时访问被拒绝
- json - 如何处理 loadrunner 请求正文中的特殊字符连字符
- go - 使用 go-redis 库时如何连接到故障转移的复制 Redis
- mysql - 如何在 MySQL 中的多个列中搜索组合词
- javascript - 我正在使用 `react-i18next` 进行翻译,我需要为字符串的某个部分赋予样式,我该怎么做?
- java - 随机 nextInt() 作为 For 循环语句产生预期随机值的一半