[英]How to group by a property of an object in a Java List?
我有一个资源对象列表。 资源对象定义为:
class Resource {
String ip;
String subnet;
// other properties...
}
我需要一个像地图这样的数据结构,其中键是一个子网中的随机资源,值是其他子网中所有资源的列表。
例如,如果S
表示子网, R
表示资源,则列表具有:
S1R1, S1R2, S2R1, S2R2, S3R1 and S3R2
预期输出为:
S1R1 -> S2R1, S2R2, S3R1, S3R2
S2R2 -> S1R1, S1R2, S3R1, S3R2
S3R1 -> S1R1, S1R2, S2R1, S2R2
我尝试使用流并收集基于子网的分组,但不确定如何从此处继续。
Map<String, Set<Resource>> grouped = resourceList.stream()
.collect(Collectors.groupingBy(Resource::getSubnet, Collectors.toSet()));
这不适用于groupingBy
收集器,因为它通过将属于某个组的元素传递到每个组的下游收集器来工作,而您不能告诉它传递其他组。
实现您所描述的一种方法是
TreeMap<Resource, Set<Resource>> map
= new TreeMap<>(Comparator.comparing(Resource::getSubnet));
for(Resource resource: resourceList)
map.computeIfAbsent(resource, x -> new HashSet<>(resourceList)).remove(resource);
map.forEach((resource,set) -> System.out.println(resource+" -> "
+set.stream().map(Resource::toString).collect(Collectors.joining(", "))));
给定列表S1R1, S1R2, S2R1, S2R2, S3R1, S3R2
S1R1 -> S3R2, S2R1, S2R2, S3R1
S2R1 -> S3R2, S1R2, S3R1, S1R1
S3R1 -> S1R2, S2R1, S2R2, S1R1
尽管未定义Set
元素的顺序,但实际上并不是随机选择Map
的键,它是每个子网中第一个遇到的资源。
您可以通过两个链式流操作来完成此操作
Map<Resource, Set<Resource>> map = resourceList.stream()
.collect(Collectors.groupingBy(Resource::getSubnet, Collectors.toSet()))
.values().stream()
.collect(Collectors.toMap(
set -> set.iterator().next(),
set -> {
Set<Resource> other = new HashSet<>(resourceList);
other.removeAll(set);
return other;
}));
在这里,从每个组中选出的资源确实是未指定的。 与基于TreeMap
的方法不同,您必须知道实际的Resource
(或尝试全部使用)来查找组。 TreeMap
允许使用来自同一子网的任何Resource
来查找组。
我不确定子网是如何工作的,但是您必须弄清楚下面的关系( isSubNetOf )。
BiPredicate<Resource, Resource> isSubNetOf = (parent, subnet) -> ???;
Map<Resource, Set<Resource>> resourceToSubnets = resourceList.stream()
.collect(toMap(
Function.identity(),
x -> resourceList.stream().filter(v -> isSubNetOf.test(x, v)).collect(toSet())
));
如果需要Map<String, Set<Resource>>
将Function.identity()
更改为所需的Resource::getIp
或Resource::getSubnet
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.