假设我有一个嵌套对象,其中包含一对不同的 String-Integer 对象(我们将每个这样的对称为
endpoint
)。有一个名为 pair
的列表,其中恰好包含 2 个 endpoint
对象。另一个名为 pairs
的列表可以包含任意数量(例如 n
)pair
条目,我需要在新对象中收集每对唯一的字符串及其相应的整数值。
考虑现有对象的以下类:
public class Endpoint {
private String key;
private Integer number;
public Endpoint(String key, Integer number) {
this.key = key;
this.number = number;
}
// Getters, Setters and toString()
}
public class Pair {
// It will have exactly 2 entries
List<Endpoint> pair;
public Pair(List<Endpoint> pair) {
this.pair = pair;
}
// Getters, Setters and toString()
}
考虑以下对象(转换前),其中
pairs
是 List<Pair>
。 pairs
中的条目可以按任意顺序排列:
pairs: [
pair: [{"p1",1000},{"p2",2000}],
pair: [{"p1",3000},{"p3",4000}],
pair: [{"p2",5000},{"p3",6000}],
pair: [{"p1",2000},{"p2",3000}],
pair: [{"p1",2001},{"p2",3001}],
pair: [{"p1",4000},{"p3",5000}],
pair: [{"p1",4001},{"p3",5001}],
pair: [{"p2",6000},{"p3",7000}],
pair: [{"p2",6001},{"p3",7001}]
]
考虑使用以下类来填充结果:
public class CustomEndpoint {
private String key;
// `numbers` can have any number of entries
private List<Integer> numbers;
public CustomEndpoint(String key, List<Integer> numbers) {
this.key = key;
this.numbers = numbers;
}
// Getters, Setters and toString()
}
public class CustomPair {
// It will have exactly 2 entries
List<CustomEndpoint> pair;
public CustomPair(List<CustomEndpoint> pair) {
this.pair = pair;
}
// Getters, Setters and toString()
}
我需要按如下方式收集:
custom-pairs: [
custom-pair: {[{"p1", [1000,2000,2001]}, {"p2", [2000,3000,3001]}]},
custom-pair: {[{"p1", [3000,4000,4001]}, {"p3", [4000,5000,5001]}]},
custom-pair: {[{"p2", [5000,6000,6001]}, {"p3", [6000,7000,7001]}]}
]
其中
custom-pairs
是 List<CustomPair>
。 numbers
列表中的条目顺序必须保持与输入 pair
相同。例如,由于 p1 中的 1000
与 p2 中的 2000
配对,如果 1000
是 p1 的 numbers
列表中的第一个条目,那么 2000
也必须是 p2 的 numbers
列表中的第一个条目,对于p1 和 p2 配对在一起的组合。
如何使用 Java 中的流来做到这一点?
在您对课程及其结构进行澄清之后,我更新了我的答案。
基本上,您可以通过两个包含端点的键对列表
Pair
中的 pairs
元素进行分组。为了使代码更具可读性,我在您的 Pair
类 (getPairKeys
) 中添加了一个方法,该方法返回链接在一起的两个端点的键,但如果您愿意,您可以通过简单地在流中链接键来避免这种情况.
按键对
Pair
元素进行分组后,您将得到一个 Map
,其中每个链式键映射到具有相同键的 n 个 Pair
实例。此时,您可以流式传输 Map
条目,将每个条目映射到 CustomPair
,按第一个 CustomEndpoint
的第一个数字对它们进行排序,并最终收集实例。
为了使我的解决方案发挥作用,我假设
equals
(以及hashCode
)的实现存在于Pair
和Endpoint
中。另外,正如我之前所说,我在 getPairKeys
类中添加了 Pair
方法来获取映射每个 String
的 Pair
,并在 getFirstPairInitialNumber
类中添加了 CustomPair
方法来建立排序顺序其中CustomPair
。我刚才提到的所有代码都可以在下面的链接中查阅。我不想将其发布在这里,以避免文字墙并只关注实际的解决方案。
List<CustomPair> listRes = pairs.stream()
.collect(Collectors.groupingBy(Pair::getPairKeys)) //Grouping the Pairs by the keys of the two EndPoints (key1:key2)
.entrySet().stream() //Streaming the entries of the map
.map(entry -> {
String key1 = null, key2 = null;
//Lists for the values of the CustomEndpoint
List<Integer> listValues1 = new ArrayList<>();
List<Integer> listValues2 = new ArrayList<>();
//Retrieving the keys and adding each pair's number to the respective lists
for (Pair p : entry.getValue()) {
key1 = p.getPair().get(0).getKey();
key2 = p.getPair().get(1).getKey();
listValues1.add(p.getPair().get(0).getNumber());
listValues2.add(p.getPair().get(1).getNumber());
}
//Returning the new CustomPair in place of the two grouped by Pair
return new CustomPair(new ArrayList<>(List.of(
new CustomEndpoint(key1, listValues1),
new CustomEndpoint(key2, listValues2))));
})
.sorted(Comparator.comparing(CustomPair::getFirstPairInitialNumber)) //Ordering the CustomPair by the beginning of their endpoint range
.collect(Collectors.toList()); //Collecting the CustomPair
这是测试代码的更新链接
Map<List<String>, List<Pair>> groupedPairs = pairs.stream()
.collect(Collectors.groupingBy(p -> List.of(
p.getPair().getFirst().getKey(),
p.getPair().getLast().getKey())));
List<CustomPair> customPairs = groupedPairs.entrySet().stream()
.map(e -> new CustomPair(List.of(
new CustomEndpoint(
e.getKey().getFirst(),
e.getValue().stream()
.map(p -> p.getPair().getFirst().getNumber())
.toList()),
new CustomEndpoint(
e.getKey().getLast(),
e.getValue().stream()
.map(p -> p.getPair().getLast().getNumber())
.toList()))))
.toList();
首先按键将
Pair
对象分组为 Map<List<String>, List<Pair>>
,其中键是包含 List<String>
的键的 2 元素 Pair
,值是包含这两个元素的所有对的列表键。 然后将 Map
中的每个条目映射到 CustomPair
。