我有一个关于如何应用 Java 8 group by 的问题。书籍和其他问题/论坛中的分组解决方案说明了在对象属性上的应用,例如 getter 方法,但我的情况有点不同。我有一个数据库查询结果集,它是列表中的列表。内部列表有时是 List<Long>
或List<String>
,我正在尝试转换为 map (使用分组依据)。
由于没有附加接口(interface)/类属性,所以我不确定在 Collectors.groupingBy()
中使用什么 lambda 表达式/方法引用。我尝试了 Function.identity(),但这似乎不起作用。
例如这是一个虚拟结果集:
List<List> resultSet = new ArrayList<>(); // didn't declare List<List<Long>> to keep it generic for both Long, and String.
List<Long> tmp = new ArrayList<>();
tmp.add(1L);
tmp.add(20L);
resultSet.add(tmp);
tmp = new ArrayList<>();
tmp.add(1L);
tmp.add(30L);
resultSet.add(tmp);
tmp = new ArrayList<>();
tmp.add(2L);
tmp.add(10L);
resultSet.add(tmp);
假设数据库结果集具有上面的值:
[[1, 20], [1, 30], [2, 10]]
那么预期输出是:{1=[20,30], 2=[10]}
类似地 [[1, abc], [1, xyz], [2, pqr]]
考虑List<List<String>>
它应该结果:{1=[abc,xyz], 2=[pqr]}
我想出了以下中间代码,但它甚至还不够接近:
List<Object> onlyKeys = resultSet.stream().map(a -> a.get(0)).distinct().collect(Collectors.toList());
输出:[1,2]
Map grouup1 = resultSet.stream().collect(Collectors.groupingBy(o -> o.get(0)));
输出:{1=[[1, 20], [1, 30]], 2=[[2, 10]]}
我有一个使用 for 循环、嵌套 if 条件的命令式解决方案,这是我完全想避免的。
最佳答案
使用 groupingBy 收集器,将列表的第一个元素作为键,然后将第二个元素传递给 mapping
下游收集器。最后使用 toList 收集器将值累积到 List 中。由于您有不同的类型,例如 Long、String 等。值得为转换编写一个通用方法并将其用于所有类型。这是它的样子。
private static <T> Map<T, List<T>> keyValListToMap(List<List<T>> source) {
return source.stream()
.collect(Collectors.groupingBy(l -> l.get(0),
Collectors.mapping(l -> l.get(1), Collectors.toList())));
}
这是您的客户端代码。
Map<Long, List<Long>> result = keyValListToMap(resultSet);
关于java - 如何对结果集响应使用 Group by,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59858817/