gpt4 book ai didi

java - 如何按 Java 列表中对象的属性进行分组?

转载 作者:行者123 更新时间:2023-11-30 02:08:41 25 4
gpt4 key购买 nike

我有一个资源对象列表。资源对象定义为:

class Resource {
String ip;
String subnet;
// other properties...
}

我需要一个像 map 这样的数据结构,其中键是一个子网中的随机资源,值是其他子网中所有资源的列表。

例如,如果 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 来查找组。

关于java - 如何按 Java 列表中对象的属性进行分组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50723466/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com