java - 多键串流分组
问题描述
我想在 java 中使用流来根据多个字段对长长的对象列表进行分组。这将导致地图地图地图地图地图地图地图地图地图。
我怎样才能只从那个复杂的流中提取列表?
这是一些演示示例代码(字符串列表,寻找具有相同长度和首字母的组)。我对键不感兴趣,只对结果分组的实体感兴趣。
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 操作的一部分。我知道它可以通过例如循环生成的地图结构来完成。但是有没有办法使用流来实现它?
[
[A],
[AA],
[AAA, ABA],
[B],
[BB],
[BBB, BAB],
[C],
[CC],
[CCC, CAC]
]
解决方案
而不是使用 cascaded 创建嵌套组Collectors.groupingBy
,您应该按复合键进行分组:
Map<List<Object>, List<String>> map = strings.stream()
.collect(Collectors.groupingBy(s -> Arrays.asList(s.charAt(0), s.length())));
然后,只需获取地图值:
List<List<String>> result = new ArrayList<>(map.values());
如果您使用的是 Java 9+,您可能需要从 更改Arrays.asList
为List.of
来创建复合键。
这种方法非常适合您的情况,因为您声明您对保留密钥不感兴趣,并且因为List
两者返回的实现Arrays.asList
并且在它们和方法List.of
方面都有很好的定义,即它们可以安全地用作任何密钥.equals
hashCode
Map
推荐阅读
- r - * 与 .* 在 R 中使用正则表达式
- flutter - 1 QuerySnapshot 在 Flutter Web 应用程序中返回 null 但在 Android 控制台中给出结果
- appinsights - 为什么我的日志消息总是有顶级操作名称?
- css - 为什么使用 React Native 会模糊图像?
- scala - 如何编译一个凿码?有没有在线编译器?
- python - Python中的算法 - 将具有相同爱好的人分组
- swift - 为什么结构类型 UUID 不可发送?
- r - PCA 作为插入符号中 KNN 模型的预处理不起作用
- angular - How to filter an array of object by comparing its id with the values of a different array
- python - 在 SciPy 中拟合分布时如何检查收敛性