通过索引比较两个列表的流

问题描述 投票:0回答:2

我有 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 逻辑。

java java-stream
2个回答
0
投票

一种解决方案是使用第三方库,该库能够将流对压缩成单个流对。 使用这种方法,两个流将被压缩成包含元素对的单个流,具有相同名称的对将通过调用 Stream.filter()

 来保留,然后最后剩余的过滤元素对将具有对他们采取行动。

Stack Overflow 答案

使用 JDK8 和 lambda 压缩流 (java.util.stream.Streams.zip) 包含以这种方式压缩两个流的各种解决方案。

番石榴

Google 的

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));
    

0
投票
一种方法是流式传输索引而不是列表,并使用

List.get(i)

 从每个 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)));
请注意,为了使这种方法有效,列表必须支持快速(例如恒定时间)随机访问。  这通常意味着任何实现 

RandomAccess

 接口的列表,例如 ArrayList
Arrays.asList()

© www.soinside.com 2019 - 2024. All rights reserved.