作者热门文章
- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我想在 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.asList
和List.of
在 equals
和 hashCode
方法方面定义明确,即它们可以安全地用作任何 中的键 map
.
关于java - 按多个键流分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54693923/
我是一名优秀的程序员,十分优秀!