java循环交叉_交叉两个不同对象类型的集合java 8
直接等效于嵌套循环
List result = listOne.stream()
.flatMap(one -> listTwo.stream()
.filter(two -> one.getMyFirstProperty().equals(two.getMyOtherProperty()))
.map(two -> new RootSampleClass(one, two)))
.collect(Collectors.toList());
重点是直接等效,其中包括做n×m操作的不良表现.
更好的解决方案是将其中一个列表转换为支持有效查找的数据结构,例如,哈希映射.此考虑因素与您使用的API的问题无关.既然您要求Stream API,您可以这样做:
Map> tmp=listOne.stream()
.collect(Collectors.groupingBy(SampleClassOne::getMyFirstProperty));
List result = listTwo.stream()
.flatMap(two -> tmp.getOrDefault(two.getMyOtherProperty(), Collections.emptyList())
.stream().map(one -> new RootSampleClass(one, two)))
.collect(Collectors.toList());
请注意,两种解决方案都会创建所有可能的配对,以便在一个或两个列表中多次出现属性值.如果属性值在每个列表中都是唯一的,例如ID,则可以使用以下解决方案:
Map tmp=listOne.stream()
.collect(Collectors.toMap(SampleClassOne::getMyFirstProperty, Function.identity()));
List result = listTwo.stream()
.flatMap(two -> Optional.ofNullable(tmp.get(two.getMyOtherProperty()))
.map(one -> Stream.of(new RootSampleClass(one, two))).orElse(null))
.collect(Collectors.toList());
如果您不介意可能执行双重查找,则可以使用以下更易读的代码替换最后一个解决方案:
Map tmp=listOne.stream()
.collect(Collectors.toMap(SampleClassOne::getMyFirstProperty, Function.identity()));
List result = listTwo.stream()
.filter(two -> tmp.containsKey(two.getMyOtherProperty()))
.map(two -> new RootSampleClass(tmp.get(two.getMyOtherProperty()), two))
.collect(Collectors.toList());