我有 2 个不同的列表:
List1
和 List2
,我想对元素具有相同 getName()
值的每个索引执行操作:
for (int i = 0; i < 5; i++) {
if (list1.get(i).getName().equals(list2.get(i).getName())) {
// TODO
}
}
有没有办法使用 Java 流来做到这一点? 我已经尝试过逻辑:
if (List1().stream().anymatch(x -> List2().stream().anymatch(y -> x.getName().equals(y.getName))))) {
// TODO
}
这是可行的,但是
List1
的第一个对象(索引)与List2
的每个对象(索引)进行比较。
我需要的是
List1
的第一个对象(索引)与List2
的第一个对象(索引)进行比较,第二个索引与第二个对象(索引)进行比较,依此类推。
如何使用流而不是 for 循环来编写 if 逻辑。
一种解决方案是使用第三方库,该库能够将流对压缩成单个流对。 使用这种方法,两个流将被压缩成包含元素对的单个流,具有相同名称的对将通过调用 Stream.filter()
使用 JDK8 和 lambda 压缩流 (java.util.stream.Streams.zip) 包含以这种方式压缩两个流的各种解决方案。
番石榴Guava 库提供了 Streams.zip
Streams.zip(list1.stream(), list2.stream(), Map::entry)
.filter(e -> e.getKey().getName().equals(e.getValue().getName()))
.forEachOrdered(e ->
System.out.println("Match: " + e.getKey() + ", " + e.getValue()));
流式传输StreamEx库提供了多种zip方法,包括StreamEx.zip
EntryStream.zip
:
EntryStream.zip(list1, list2)
.filterKeyValue((k, v) -> k.getName().equals(v.getName()))
.forKeyValue((k, v) -> System.out.println("Match: " + k + ", " + v));
List
检索元素。
IntStream.range(0, list1.size())
.mapToObj(i -> Map.entry(list1.get(i), list2.get(i)))
.filter(e -> e.getKey().getName().equals(e.getValue().getName()))
.forEachOrdered(e ->
System.out.println("Match: " + e.getKey() + ", " + e.getValue()));
或
IntStream.range(0, list1.size())
.filter(i -> list1.get(i).getName().equals(list2.get(i).getName()))
.forEachOrdered(i ->
System.out.printf("Match at index %s: %s, %s\n", i, list1.get(i), list2.get(i)));
请注意,为了使这种方法有效,列表必须支持快速(例如恒定时间)随机访问。 这通常意味着任何实现 接口的列表,例如 ArrayList
和 Arrays.asList()
。