Java中在迭代時新增元素的3種方法

banq發表於2024-03-22

迭代List是Java中的常見操作,但是在迭代時向其中新增元素需要仔細考慮,以避免出現異常並確保程式碼的正確性。

在本教程中,我們將討論在迭代期間向集合新增元素的幾種方法。

1、使用ListIterator類
一種常見的方法是ListIterator,它提供列表的雙向遍歷和修改功能。

考慮以下示例,我們在遇到Python後將元素JavaScript新增到程式語言列表中:

List<String> programmingLanguages = new ArrayList<>(List.of(<font>"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);
}

在提供的程式碼中,我們初始化一個名為programmingLanguages的列表,其中包含字串(Java、Python和C++)。此外,我們使用listIterator.next()方法迭代列表的元素。

當我們遇到Python元素時,我們使用listIterator.add(“JavaScript”)動態地在它後面立即插入字串JavaScript。

最後,測試斷言修改後的列表與預期結果匹配,確保在列表中的Python之後成功新增JavaScript 。


讓我們將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);
}

在此數字場景中,我們使用ListIterator來迭代整數列表。當遇到數字 2 時,該值會乘以 10 並動態新增到列表中。

2、帶副本的增強型 For 迴圈
另一種策略涉及建立原始列表的副本並在修改原始列表時對其進行迭代。

考慮以下示例,我們將原始列表中每個單詞的大寫版本新增到列表本身:

@Test
public void givenStringList_whenAddElementWithEnhancedForLoopAndCopy_thenModifiedList() {
    List<String> copyOfWords = new ArrayList<>(programmingLanguages);
    for (String word : copyOfWords) {
        programmingLanguages.add(word.toUpperCase());
    }
    assertIterableEquals(Arrays.asList(<font>"Java", "Python", "C++", "JAVA", "PYTHON", "C++"), programmingLanguages);
}

在增強的 for 迴圈中,我們迭代copyOfWords列表的每個元素,將相應的值轉換為大寫,並將其新增到原始列表programmingLanguages中。

值得注意的是,此插入過程可確保使用現有單詞的大寫版本擴充套件原始列表,同時保持序列完整性。換句話說,programmingLanguages列表將包含原始元素,後跟新新增的大寫版本。

現在,讓我們將增強的 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);
}

在這裡,我們進行迭代,將每個元素乘以 2,並將其新增到原始列表中。與字串方法相同,

3、利用 Java 8 流方法
Java 8 Streams提供了一種在迭代期間向列表新增元素的簡潔方法。

考慮以下示例,我們使用 Java 8 Streams 將字串JavaScript新增到programmingLanguages列表中:

@Test
public void givenStringList_whenConvertToUpperCaseWithJava8Stream_thenModifiedList() {
    programmingLanguages = programmingLanguages.stream().map(String::toUpperCase).collect(Collectors.toList());
    assertIterableEquals(Arrays.asList(<font>"JAVA", "PYTHON", "C++"), programmingLanguages);
}

在此程式碼片段中,我們利用對映操作,使用toUpperCase方法將列表中的每個字串元素轉換為其等效的大寫字母。然後,我們使用Collectors.toList()將轉換後的元素收集到一個新列表中。

但是,必須注意的是,每個新元素都會直接更改列表中相應的原始元素。這種直接更改展示了原始列表內容的轉換,同時保留了其完整性。

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

在此測試方法中,我們利用對映操作,列表中的每個數字元素都會經過一次乘以 3 的轉換。此外,結果流透過Collectors.toList()收集到一個新列表中。

 

相關文章