java - 按多个键流分组

标签 java java-8 java-stream

我想在 java 中使用流来根据多个字段对长对象列表进行分组。这将导致 map 的 map map 的 map map 的 map ......列表的 map 。

我怎样才能只从那个复杂的流中提取列表?

这里有一些示例代码用于演示(字符串列表,寻找具有相同长度和首字母的组)。我对 key 不感兴趣,只对生成的分组实体感兴趣。

List<String> strings = ImmutableList.of("A", "AA", "AAA", "B", "BB", "BBB", "C", "CC", "CCC", "ABA", "BAB", "CAC");

Map<Character, Map<Integer, List<String>>> collect = strings.stream().collect(
        groupingBy(s -> s.charAt(0),
                groupingBy(String::length)
        )
);

这将产生以下结果

My Map =
{
    A =
    {
        1 = [A]
        2 = [AA]
        3 = [AAA, ABA]
    }
    B =
    {
        1 = [B]
        2 = [BB]
        3 = [BBB, BAB]
    }
    C =
    {
        1 = [C]
        2 = [CC]
        3 = [CCC, CAC]
    }
}

我感兴趣的实际上只是上述结果的列表,我想理想地把它作为 groupby 操作的一部分。我知道这可以通过循环生成的 map 结构来完成。但是有没有办法使用流来实现它?

 [
     [A],
     [AA],
     [AAA, ABA],
     [B],
     [BB],
     [BBB, BAB],
     [C],
     [CC],
     [CCC, CAC]
 ]

最佳答案

与其使用级联 Collectors.groupingBy 创建嵌套组,不如按复合键分组:

Map<List<Object>, List<String>> map = strings.stream()
        .collect(Collectors.groupingBy(s -> Arrays.asList(s.charAt(0), s.length())));

然后,只需获取 map 值:

List<List<String>> result = new ArrayList<>(map.values());

如果您使用的是 Java 9+,您可能希望将 Arrays.asList 更改为 List.of 以创建复合键。

这种方法非常适合您的情况,因为您声明您对保留 key 不感兴趣,并且因为 Arrays.asListList.ofequalshashCode 方法方面定义明确,即它们可以安全地用作任何 中的键 map .

关于java - 按多个键流分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54693923/

相关文章:

Java流形成 map 问题

java - hibernate + "ON DUPLICATE KEY"逻辑

linux - Java 8 Javadoc 与 XJC 警告和错误

java - 使用 Stream API 将两个列表有条件地缩减为包含两个元素的单个列表

Eclipse、lambda 和 Java 8 模板

java - 如何理解这个 Java 8 Stream collect() 方法?

java-8 - 与从迭代器创建的流的并行性

java - 如何停止socket在循环java中不断写入数据

java - 如何使用 Java 读取文件内容并将其存储在数据库中?

java - LibGDX 当敌人重叠时让一颗子弹只杀死一个敌人