1. Introduction
1.导言
Iterating over a List is a common operation in Java, but adding elements to it while iterating requires careful consideration to avoid exceptions and ensure the correctness of the code.
对 List 进行迭代是 Java 中的一种常见操作,但在迭代时添加元素需要仔细考虑,以避免 异常并确保代码的正确性。
In this tutorial, we’ll discuss several methods for adding elements to a collection during iteration.
在本教程中,我们将讨论在迭代过程中将元素添加到集合的几种方法。
2. Utilizing the ListIterator Class
2.利用 ListIterator 类
One common approach is a ListIterator, which provides bidirectional traversal and modification capabilities for lists.
一种常见的方法是 ListIterator ,它为列表提供了双向遍历和修改功能。
2.1. String Scenario
2.1 字符串情景
Consider the following example, where we add the element JavaScript to the list of programming languages after encountering Python:
请看下面的示例,在遇到 Python 之后,我们将 JavaScript 元素添加到编程语言列表中:
List<String> programmingLanguages = new ArrayList<>(List.of("Java", "Python", "C++"));
@Test
public void givenList_whenAddElementWithListIterator_thenModifiedList() {
ListIterator<String> listIterator = programmingLanguages.listIterator();
while (listIterator.hasNext()) {
String language = listIterator.next();
if (language.equals("Python")) {
listIterator.add("JavaScript");
}
}
assertIterableEquals(Arrays.asList("Java", "Python", "JavaScript", "C++"), programmingLanguages);
}
In the provided code, we initialize a List named programmingLanguages containing the strings (Java, Python, and C++). In addition, we iterate through the elements of the list using the listIterator.next() method.
在提供的代码中,我们初始化了一个名为 programmingLanguages 的 List,其中包含字符串(Java、Python 和 C++)。此外,我们使用 listIterator.next() 方法遍历列表中的元素。
When we encounter the element Python we dynamically insert the string JavaScript immediately after it, using listIterator.add(“JavaScript”).
当我们遇到元素 Python 时,我们将使用 listIterator.add(“JavaScript”) 动态地在其后面插入字符串 JavaScript 。
Finally, the test asserts that the modified list matches the expected result, ensuring the successful addition of JavaScript after Python in the list.
最后,测试断言修改后的列表与预期结果一致,确保在列表中 Python 之后成功添加 JavaScript 。
2.2. Numeric Scenario
2.2.数字情景
Let’s apply the ListIterator approach to a list of integers, adding double the value when encountering the number 2:
让我们将 ListIterator 方法应用到整数列表中,在遇到数字 2 时将数值加倍:
List<Integer> numbers = new ArrayList<>(List.of(1, 2, 3));
@Test
public void givenNumericalList_whenMultiplyElementWithListIterator_thenModifiedList() {
ListIterator<Integer> listIterator = numbers.listIterator();
while (listIterator.hasNext()) {
int num = listIterator.next();
if (num == 2) {
listIterator.add(num * 10);
}
}
assertIterableEquals(Arrays.asList(1, 2, 20, 3), numbers);
}
In this numeric scenario, we use the ListIterator to iterate through a list of integers. When the number 2 is encountered, the value is multiplied by 10 and dynamically added to the list.
在此数字场景中,我们使用 ListIterator 遍历整数列表。当遇到数字 2 时,该值将乘以 10 并动态添加到列表中。
3. Enhanced For Loop with a Copy
3.复制增强型 For 循环
Another strategy involves creating a copy of the original list and iterating over it while modifying the original list.
另一种策略是创建原始列表的副本,并在修改原始列表的同时对其进行迭代。
3.1. String Scenario
3.1 字符串情景
Consider the following example, where we add the uppercase version of each word in the original list to the list itself:
请看下面的例子,我们将原始列表中每个单词的大写版本添加到列表本身:
@Test
public void givenStringList_whenAddElementWithEnhancedForLoopAndCopy_thenModifiedList() {
List<String> copyOfWords = new ArrayList<>(programmingLanguages);
for (String word : copyOfWords) {
programmingLanguages.add(word.toUpperCase());
}
assertIterableEquals(Arrays.asList("Java", "Python", "C++", "JAVA", "PYTHON", "C++"), programmingLanguages);
}
Within the enhanced for loop, we iterate over each element of the copyOfWords list, convert the corresponding value to uppercase, and add it to the original list programmingLanguages.
在增强型 for 循环中,我们遍历 copyOfWords 列表中的每个元素,将相应值转换为大写,并将其添加到原始列表 programmingLanguages 中。
Notably, this insertion process ensures that the original list is expanded with the uppercase versions of the existing words while maintaining the sequence integrity. In other words, the programmingLanguages list will contain the original elements followed by the newly added uppercase versions.
值得注意的是,这一插入过程可确保在保持序列完整性的同时,用现有单词的大写版本扩展原始列表。换句话说, 编程语言列表将包含原始元素和新添加的大写版本。
3.2. Numeric Scenario
3.2.数字情景
Now, let’s apply the enhanced for-loop approach to a list of integers, adding each number multiplied by 2:
现在,让我们对整数列表应用增强的 for 循环方法,将每个数字乘以 2 相加:
List<Integer> numbers = new ArrayList<>(List.of(1, 2, 3));
@Test
public void givenList_whenAddElementWithEnhancedForLoopAndCopy_thenModifiedList() {
List<Integer> copyOfNumbers = new ArrayList<>(numbers);
for (int num : copyOfNumbers) {
numbers.add(num * 2);
}
assertIterableEquals(Arrays.asList(1, 2, 3, 2, 4, 6), numbers);
}
Here, we iterate, multiply each element multiplied by 2, and add it to the original list. Same as the string approach,
在这里,我们进行迭代,将每个元素乘以 2,然后将其添加到原始列表中。与字符串方法相同、
4. Utilizing the Java 8 Stream Approach
4.利用 Java 8 流方法
Java 8 Streams provide a concise way to add elements to a list during iteration.
Java 8 Streams 提供了一种在迭代过程中将元素添加到列表的简洁方法。
4.1. String Scenario
4.1 字符串方案
Consider the following example, where we use Java 8 Streams to add the string JavaScript to the list of programmingLanguages:
请看下面的示例,我们使用 Java 8 Streams 将字符串 JavaScript 添加到 programmingLanguages 列表中:
@Test
public void givenStringList_whenConvertToUpperCaseWithJava8Stream_thenModifiedList() {
programmingLanguages = programmingLanguages.stream().map(String::toUpperCase).collect(Collectors.toList());
assertIterableEquals(Arrays.asList("JAVA", "PYTHON", "C++"), programmingLanguages);
}
In this code snippet, we utilize the map operation to transform each string element in the list to its uppercase equivalent using the toUpperCase method. Then, we collect the transformed elements into a new list using Collectors.toList().
在此代码片段中,我们利用 map 操作,使用 toUpperCase 方法将列表中的每个字符串元素转换为对应的大写字母。然后,我们使用 Collectors.toList() 将转换后的元素收集到一个新的列表中。
However, it’s essential to note that each new element directly alters the corresponding original element in the list in place. This direct alteration demonstrates the transformation of the original list’s contents while preserving its integrity.
不过,必须注意的是,每个新元素都会直接更改列表中相应的原始元素。这种直接更改展示了原始列表内容的转变,同时保持了其完整性。
4.2. Numeric Scenario
4.2.数字情景
Let’s apply the Java 8 Stream approach to a list of integers, multiplying each number by 3:
让我们将 Java 8 Stream 方法应用于整数列表,将每个数字乘以 3:
@Test
public void givenNumericalList_whenMultiplyByThreeWithJava8Stream_thenModifiedList() {
numbers = numbers.stream().map(num -> num * 3).collect(Collectors.toList());
assertIterableEquals(Arrays.asList(3, 6, 9), numbers);
}
In this test method, we utilize the map operation, each numeric element in the list undergoes a transformation where it is multiplied by 3. In addition, the resulting stream is collected into a new list through Collectors.toList().
在此测试方法中,我们使用了 map 操作,列表中的每个数字元素都要经过乘以 3 的转换。此外,通过 Collectors.toList() 将生成的数据流收集到一个新列表中。
5. Conclusion
5.结论
In conclusion, we explored diverse methods, including ListIterator, enhanced for loop with a copy, and Java 8 Streams, for adding elements to a list during iteration in Java.
总之,我们探索了多种方法,包括 ListIterator, 带副本的增强型 for 循环,以及 Java 8 Streams,用于在 Java 中迭代过程中向列表添加元素。
As usual, the accompanying source code can be found over on GitHub.
与往常一样,您可以在 GitHub 上找到随附的源代码。