Java8实现:Stream<A>和Stream<B>按照复数个匹配key进行匹配,将匹配成功的Stream<A>和Stream<B>以List<Pair<A,B>>的形式返回。已知Stream<A>和Stream<B>已经按匹配key排好序了,要求减少嵌套循环来提高性能
时间: 2023-12-02 18:05:41 浏览: 59
可以使用Java8中的Stream API来实现这个功能,具体步骤如下:
1. 定义一个方法,接收两个参数,分别为Stream<A>和Stream<B>:
```
public static <A, B, K extends Comparable<? super K>> List<Pair<A, B>> match(Stream<A> streamA, Stream<B> streamB, Function<A, K> keyA, Function<B, K> keyB) {
// ...
}
```
其中,`K extends Comparable<? super K>` 表示匹配 key 的类型必须是可比较的,`keyA` 和 `keyB` 分别为从 A 和 B 中提取匹配 key 的函数。
2. 将 Stream<A> 和 Stream<B> 转换成 Map<K, List<A>> 和 Map<K, List<B>>,其中 K 为匹配 key 的类型:
```
Map<K, List<A>> mapA = streamA.collect(Collectors.groupingBy(keyA));
Map<K, List<B>> mapB = streamB.collect(Collectors.groupingBy(keyB));
```
这里使用 `groupingBy` 方法对 Stream 进行分组,将具有相同匹配 key 的元素放到一个 List 中。
3. 遍历 Map<K, List<A>>,对于每一个 key,将 List<A> 和 List<B> 进行匹配,将匹配成功的元素以 List<Pair<A,B>> 的形式返回:
```
List<Pair<A, B>> result = mapA.entrySet().stream()
.flatMap(entry -> {
K key = entry.getKey();
List<A> listA = entry.getValue();
List<B> listB = mapB.get(key);
if (listB == null) {
return Stream.empty();
}
return listA.stream().flatMap(a -> listB.stream().map(b -> new Pair<>(a, b)));
})
.collect(Collectors.toList());
```
这里使用 `flatMap` 方法对 Map 中的每个 entry 进行遍历,如果 mapB 中没有对应的 List<B>,则返回空 Stream;否则,将 List<A> 和 List<B> 进行匹配,将匹配成功的元素以 List<Pair<A,B>> 的形式返回。
完整的代码如下:
```
public static <A, B, K extends Comparable<? super K>> List<Pair<A, B>> match(Stream<A> streamA, Stream<B> streamB, Function<A, K> keyA, Function<B, K> keyB) {
Map<K, List<A>> mapA = streamA.collect(Collectors.groupingBy(keyA));
Map<K, List<B>> mapB = streamB.collect(Collectors.groupingBy(keyB));
return mapA.entrySet().stream()
.flatMap(entry -> {
K key = entry.getKey();
List<A> listA = entry.getValue();
List<B> listB = mapB.get(key);
if (listB == null) {
return Stream.empty();
}
return listA.stream().flatMap(a -> listB.stream().map(b -> new Pair<>(a, b)));
})
.collect(Collectors.toList());
}
```
注意:这里假设匹配 key 的类型是可比较的,如果不可比较,需要使用自定义的比较器来进行比较。此外,由于使用了 Stream API,代码的可读性和易于维护性得到了很大提升,但是需要注意Stream的惰性求值特性,需要在最后调用 collect 方法触发计算。
阅读全文