CodeGym /課程 /JAVA 25 SELF /集合的轉換

集合的轉換

JAVA 25 SELF
等級 28 , 課堂 1
開放

1. 轉換集合的元素

在程式設計中,最常見的操作之一就是 集合轉換:我們手上有一個某種型別的資料集合,並需要在此基礎上建立另一個不同型別的新集合。比如,從型別為 User 的物件清單取得它們的名稱(String),或者從數字清單得到它們的平方清單。

在 Java 中最基礎也最直觀的方法是採用命令式作法,也就是使用一般的 for 迴圈(常見的是 for-each)。

範例:由字串清單取得其長度清單

假設我們有一個城市名稱的清單:

List<String> cities = List.of("倫敦", "巴黎", "東京", "紐約");

我們的任務是建立一個新清單,包含每個名稱的長度。最終結果應為:[2, 2, 2, 2]

使用迴圈 for 的解法:

import java.util.ArrayList;
import java.util.List;

public class CollectionTransform {
    public static void main(String[] args) {
        List<String> cities = List.of("倫敦", "巴黎", "東京", "紐約");
        List<Integer> lengths = new ArrayList<>(); // 建立一個新的空清單來儲存結果

        for (String city : cities) {
            // 對於 cities 中的每個元素,計算其長度...
            int length = city.length();
            // ...並將結果加入新的清單
            lengths.add(length);
        }

        System.out.println(lengths); // 輸出: [2, 2, 2, 2]
    }
}

我們先建立一個新的空集合來存放結果——轉換不會修改原始集合。為了走訪原始集合,我們使用 for-each 迴圈,並在迴圈內對每個元素套用所需的邏輯(length()),然後將結果透過 add 加入新清單。

2. 物件的轉換

我們經常會處理更複雜的資料型別。假設有一個類別 Product,需要取得其名稱(或價格)的清單。

public class Product {
    private String name;
    private double price;

    public Product(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public double getPrice() {
        return price;
    }
}

現在,基於產品清單,來取得它們的名稱清單:

import java.util.ArrayList;
import java.util.List;

public class ProductExample {
    public static void main(String[] args) {
        List<Product> products = List.of(
            new Product("筆電", 1200.0),
            new Product("滑鼠", 25.5),
            new Product("鍵盤", 75.0)
        );

        // 建立一個用來存放名稱的新清單
        List<String> productNames = new ArrayList<>();

        for (Product product : products) {
            // 對於每個 Product 物件,取得其名稱
            productNames.add(product.getName());
        }

        System.out.println(productNames); // 輸出: [筆電, 滑鼠, 鍵盤]
    }
}

邏輯相同:走訪原始集合,對每個元素呼叫所需的方法(例如 getName()),並把結果加入新的集合。

3. 處理巢狀集合

考慮一個清單的清單:有多個部門,每個部門都有自己的員工清單。目標是取得一個共同(「扁平」)的所有員工清單。

範例:合併員工清單

List<List<String>> departments = List.of(
    List.of("安娜", "鮑里斯"),
    List.of("維多利亞", "格列布", "德米特里"),
    List.of("葉蓮娜")
);

我們希望得到單一清單:[安娜, 鮑里斯, 維多利亞, 格列布, 德米特里, 葉蓮娜]

方法一:使用 addAll()

import java.util.ArrayList;
import java.util.List;

public class NestedCollectionExample {
    public static void main(String[] args) {
        List<List<String>> departments = List.of(
            List.of("安娜", "鮑里斯"),
            List.of("維多利亞", "格列布", "德米特里"),
            List.of("葉蓮娜")
        );

        List<String> allEmployees = new ArrayList<>();

        // 逐一走訪每個清單(部門)
        for (List<String> department : departments) {
            // 將當前清單中的所有元素加入總清單
            allEmployees.addAll(department);
        }

        System.out.println(allEmployees); // [安娜, 鮑里斯, 維多利亞, 格列布, 德米特里, 葉蓮娜]
    }
}

方法二:巢狀迴圈——手動完成相同的事情:

List<List<String>> departments = List.of(...);
List<String> allEmployees = new ArrayList<>();

for (List<String> department : departments) { // 外層迴圈:部門
    for (String employee : department) {      // 內層迴圈:員工
        allEmployees.add(employee);
    }
}

System.out.println(allEmployees);

兩種方式在結果上等價。方法 addAll() 本質上封裝了巢狀迴圈的邏輯,使程式碼更精簡。

4. 複雜情況與帶條件的轉換

有時轉換只需要對滿足條件的元素執行。比如,取得以字首「」開頭的城市名稱,並取其長度。這裡我們把過濾與轉換結合:if + 方法呼叫(length())。

import java.util.ArrayList;
import java.util.List;

public class ConditionalTransform {
    public static void main(String[] args) {
        List<String> cities = List.of("倫敦", "巴黎", "東京", "紐約", "紐倫堡");
        List<Integer> lengths = new ArrayList<>();

        for (String city : cities) {
            // 先檢查條件
            if (city.startsWith("紐")) {
                // 若條件成立,執行轉換
                lengths.add(city.length());
            }
        }

        System.out.println(lengths); // 輸出: [2, 3]
    }
}

模式如下:在迴圈內先透過條件(startsWith、比較、範圍檢查等)過濾元素,然後套用所需的轉換,最後把結果放進新清單。

5. 常見錯誤與陷阱

錯誤一:在遍歷期間修改原始集合。 常見錯誤——嘗試在 for-each 迴圈中直接向原始集合新增/刪除元素。這會導致錯誤與不可預期的行為。解法:一律建立新的結果清單並加以填充。

錯誤二:不正確的型別轉換。 如果你使用「未泛型化」的集合(例如透過 Object)並把元素轉成錯誤的型別,會得到 ClassCastException。請使用泛型(List<T>),並留意簽章。

錯誤三:資源使用效率不佳。 對於非常大的集合,不斷建立新清單與複製元素可能在記憶體與時間上都有明顯成本。多數日常情境下這是可接受的,但在處理大量資料時請評估複雜度,必要時優化作法。

留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION