java - 如何对结果集响应使用 Group by

标签 java java-8 java-stream

我有一个关于如何应用 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/

相关文章:

java - 带过滤器的 Spring MVC 和 RequestMapping

java - 在java中加入来自同一对象的2个流

Java - 创建具有给定范围的 IntStream,然后使用映射函数随机化每个元素

java - 通过两个参数java过滤对象

java - 如何使用 IntStream 对 int 数组的特定索引数求和?

java - 如何使用流在 Java 8 中迭代 ArrayList 的 HashMap

java扩展最终变量

Java HashMap 唯一键被覆盖 - 请查看代码和建议

Java 8 - 如何将多个字段汇总到一个 dto 中?

java - 是什么导致了 neo4j 的这种糟糕表现?