美思 [Java] 程式設計教學:使用 ArrayList 物件

Java陣列
Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

前言

ArrayList 是 Java 串列 (List) 的其中一種實作。ArrayList 內部是動態陣列 (dynamic array)。由於 Java 不支援運算子重載 (operator overloading),ArrayList 無法用 [...] 存取元素。

建立 ArrayList 物件

在預設情形下,Java 不會自動引入 ArrayList。要使用該容器的話,請引入以下物件:

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

使用以下敘述在建立 ArrayList 物件:

List<Integer> lst = new ArrayList<Integer>();

建立 ArrayList 物件的方式為使用 new 保留字,這和先前建立陣列雷同。

此處建立 ArrayList 物件,但是把變數 lst 的資料型態標註為 List,因為我們只需要 List 提供的公開方法 (public method)。

<...> 是泛型程式設計 (generic programming) 的語法。該範式將資料型態參數化,但 Java 的泛型不能用基礎型態,故此處填入 Integer

如果需要使用 ArrayList 特有的公開方法,則改用以下敘述:

ArrayList<Integer> lst = new ArrayList<Integer>();

由於 Java 泛型程式不支援基礎型態,以下敘述是錯的:

/* WRONG CODE. */
List<int> lst = new ArrayList<int>();

存取 ArrayList 物件的元素

中由於 Java 不支援運算子重載,無法使用 [...] 存取元素。替代的方式是用 get() 函式取得元素,使用 add(E) 函式從尾端新增元素。參考以下範例:

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

public class MainProgram
{
    public static void main (String[] args)
    {
        /* Create a ArrayList object. */
        List<Integer> lst = new ArrayList<Integer>();

        /* Some integer data. */
        int data[] = {1, 2, 3, 4, 5};

        for (int n : data) {
            /* Append an element to
                the rear of the list. */
            lst.add(n);
        }

        /* Retrieve an element from the list. */
        assertCond(5 == lst.get(4));
    }

    /* Home-made assert. */
    public static void assertCond (boolean cond)
    {
        if (!cond)
            throw new IllegalArgumentException("Wrong condition");
    }
}

女如果要在指定位置新增元素,則改用 add(i, E) 函式。這兩個函式是同名的,這項特性稱為函式重載 (function overloading):

for (int i = 0; i < data.length; ++i) {
    /* Add an element to a specific location
        of the list. */
    lst.add(i, data[i]);
}

add(i, E) 函式的 i 必需要介於 0 和容器寬度 (不包含) 之間,否則會拋出 IndexOutOfBoundsException 例外。

注意 set(i, E) 函式無法增長 ArrayList 寬度。故以下程式碼會引發錯誤:

for (int i = 0; i < data.length; ++i) {
    /* WRONG CODE. */
    lst.set(i, data[i]);
}

檢查特定元素是否存在

使用 contains() 函式來檢查特定元素是否存在。參考以下範例:

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

public class MainProgram
{
    public static void main (String[] args)
    {
        List<Integer> lst = new ArrayList<Integer>();

        int data[] = {1, 2, 3, 4, 5};

        for (int n : data)
            lst.add(n);

        /* Check whether an element exists. */
        assertCond(lst.contains(5));
    }

    /* Home-made assert. */
    public static void assertCond (boolean cond)
    {
        if (!cond)
            throw new IllegalArgumentException("Wrong condition");
    }
}

走訪 ArrayList 物件

使用計數器 (Counter)

ArrayList 在本質上是陣列,當然可以用計數器來走訪:

for (int i = 0; i < lst.size(); ++i)
    System.out.println(lst.get(i));

可以使用計數器的前提是程式設計者知道 ArrayList 以非負整數為索引,每次遞增 1。不一定每種容器都能使用計數器。

使用隱式迭代器 (Implicit Iterator)

ArrayList 內部隱藏迭代器,故以下程式碼是合理的:

for (int n : lst)
    System.out.println(n);

另外可以注意到此處變數 n 的資料型態是 int 而非 Integer,這裡用到了 Java 的自動型態轉換。手動在基礎型態和其相關類別間轉換的程式碼太繁瑣了,所以 Java 自動完成這些細部過程。

使用顯式迭代器 (Explicit Iterator)

既然有隱式迭代器可用,也可以直接提出顯式迭代器來用。參考以下範例:

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

public class MainProgram
{
    public static void main (String[] args)
    {
        List<Integer> lst = new ArrayList<Integer>();

        int data[] = {1, 2, 3, 4, 5};

        for (int n : data)
            lst.add(n);

        Iterator<Integer> it = lst.iterator();
        while (it.hasNext()) {
            int n = it.next();
            System.out.println(n);
        }
    }
}

此處的程式碼和前一小節的 for 迴圈是等效的,但寫起來比較長。所以這樣的模式是不必要的,本小節範例僅供參考。

關於作者

身為資訊領域碩士,美思認為開發應用程式的目的是為社會帶來價值。如果在這個過程中該軟體能成為永續經營的項目,那就是開發者和使用者雙贏的局面。

美思喜歡用開源技術來解決各式各樣的問題,但必要時對專有技術也不排斥。閒暇之餘,美思將所學寫成文章,放在這個網站上和大家分享。