迭代两个相关 ArrayList 的有效方法?



我正在寻找一种干净简单的方法来迭代两个直接相关的 ArrayLists,因为一个索引的每个索引映射到另一个索引(关系)。

目前,我正在通过一个简单的for循环来完成,我尝试查看 lambda 和for-each循环,但没有看到将其同时应用于大小相同的两个列表的方法。

首页列表:["Blue", "Red", "Green"]

第二名单:["Sky", "Roses", "Grass"]

for(int i = 0; i < firstList.size(); i++){
System.out.println(firstList.get(i) + " " + secondList.get(i));
}

结果:

Blue Sky
Red Roses
Green Grass

有没有办法使用 lambda 或for-each循环同时有效地迭代两个列表以避免使用for循环?

你所拥有的已经非常高效(假设你使用的是ArrayList),简洁易读。但是,此类方案:

我正在寻找一种干净简单的方法来迭代两个 ArrayList 直接相关,因为一个索引的每个索引都映射到索引 另一个(在关系中)。

通常需要一个定义关系的类,在您的情况下:

public class MyC {
private final String color;
private final String object;
public MyC(String color, String object) {
this.color = color;
this.object = object;
}
public String getColor(){
return color;
}
public String getObject(){
return object;
}
@Override
public String toString() {
return "MyC{" +
"color='" + color + ''' +
", object='" + object + ''' +
'}';
}
} 

那么这两个列表将合二为一:

List<MyC> list = List.of(new MyC("Blue", "Sky"), new MyC("Red", "Roses"), new MyC("Green", "Grass") );

然后您可以使用:

list.forEach(System.out::println);

dreamcrash 的答案是正确的:虽然一对数组的循环有效,但您应该通过定义自己的类来利用 Java 作为 OOP 语言。

记录

在具有新记录功能的 Java 16 中定义这样的类变得更加简单。将类编写为记录,当它的主要目的是透明且不可变地传输数据时。

默认情况下,记录非常简短。编译器隐式创建构造函数、getter、equals&hashCodetoString。您只需声明每个成员字段的类型和名称。

record ColorNoun ( String color , String noun ) {}

像使用传统类一样使用记录。 使用new进行实例化。

ColorNoun blueSky = new ColorNoun ( "Blue" , "Sky" ) ;

请注意,记录可以在方法中本地声明,也可以像传统类一样单独声明。

您可以使用 "range"-语句使用 lambda 表达式迭代索引。

https://www.baeldung.com/java-stream-indices

喜欢这个:

List<String> firstList = Arrays.asList("Blue","Red","Green");
List<String> secondList = Arrays.asList("Sky","Roses","Grass");
IntStream
.range(0, firstList.size())
.forEach(index -> 
System.out.println(String.format("%s %s", firstList.get(index), secondList.get(index)))
);

这基本上是相同的方法 - 只是使用 lambda。

摆脱基于索引的访问的唯一方法是使用不同的数据结构或使用交替迭代技术,如其他答案所示。

如果您的目的是避免使用for循环,那么您可以尝试以下方法:

Iterator<String> iterator = secondList.iterator();
firstList.forEach(s -> System.out.println(s + " " + iterator.next()));

甚至添加到StringBuilder,然后最后显示结果。

所有其他答案都是正确的,首选解决方案应始终是 @Basil Bourque 显示的解决方案,但正如其他人在评论中指出的那样,使用索引迭代非基于数组的列表不是很有效。但是,使用迭代器进行迭代应该(其中每个实现都可以提供有效的实现)。

下面是如何使用迭代器迭代 2 个列表的示例:

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.function.BiConsumer;
public class IterateTwoListsExample {
public static void main(String[] args) {
List<String> firstList = Arrays.asList("Blue","Red","Green");
List<String> secondList = Arrays.asList("Sky","Roses","Grass");
forEach(firstList, secondList, (first, second) -> System.out.printf("%s %s%n", first, second));
}
public static <T0, T1> void forEach(List<? extends T0> first, List<? extends T1> second, BiConsumer<? super T0, ? super T1> consumer) {
final Iterator<? extends T0> firstIt = first.iterator();
final Iterator<? extends T1> secondIt = second.iterator();
while (firstIt.hasNext() && secondIt.hasNext()) {
consumer.accept(firstIt.next(), secondIt.next());
}
}
}

相关内容

最新更新