HOWTO · Java
如何向 Java 陣列新增元素
了解 Java 陣列為何沒有內建的 push() 方法,以及如何使用堆疊、串列或陣列複製來新增值。
本頁內容
Java 陣列的長度是固定的,並且沒有內建的 push() 方法。要新增一個元素,請根據它應該放置的位置選擇集合:堆疊將它放在頂部,LinkedList.push() 將它插入到最前面,ArrayList.add() 將它附加到可調整大小的串列末尾。如果必須保留陣列,就把它的元素複製到一個新的更長的陣列中,並使用回傳的陣列。
以下五個 Java 範例都已在提供的執行環境中成功執行,每個範例的結束代碼都是 0。
使用 Stack.push() 實現後進先出行爲
Stack.push() 將元素新增到後進先出(LIFO)堆疊的頂部。因此,最近推入的元素會最先被 pop() 回傳。該範例推入三個字串,然後印出並移除頂部元素。
import java.util.Stack;
public class StackExample {
public static void main(String[] args) {
Stack<String> stack = new Stack<>();
stack.push("Java");
stack.push("is");
stack.push("useful");
System.out.println("Top: " + stack.peek());
System.out.println("Removed: " + stack.pop());
System.out.println("Stack: " + stack);
}
}
Top: useful
Removed: useful
Stack: [Java, is]
當後續的值應該先於先前的值被處理時,選擇這個 API,例如追蹤復原操作或待處理的工作。顯示的堆疊包含 pop() 移除頂部元素後剩餘的元素。如果只需要按原始順序保留這些值,堆疊會增加你不需要的行爲;請改用附加式的串列。
使用 LinkedList.push() 在最前面新增
LinkedList.push() 是在最前面插入,而不是附加到末尾。每次後續呼叫都會成為新的第一個元素,因此串列的順序與呼叫順序相反。
import java.util.LinkedList;
public class LinkedListExample {
public static void main(String[] args) {
LinkedList<String> values = new LinkedList<>();
values.push("Java");
values.push("is");
values.push("useful");
System.out.println(values);
}
}
[useful, is, Java]
這同樣是一種在最前面插入的操作,因此當串列被印出時,最新新增的值排在第一位。當這種順序是有意為之(例如維護一個以最新元素位於最前面的序列)時使用它。如果任務是要在末尾新增,請改用 ArrayList.add();儘管二者都會向集合中新增元素,但結果不同。
使用 ArrayList.add() 附加到可調整大小的串列
當目標是向一個可以增長的串列附加值時,使用 ArrayList.add()。該呼叫將每個值新增到末尾。ArrayList 是一個集合,而不是 Java 陣列,因此它不具有陣列那樣的固定長度。
import java.util.ArrayList;
public class ArrayListExample {
public static void main(String[] args) {
ArrayList<String> values = new ArrayList<>();
values.add("Java");
values.add("is");
values.add("useful");
System.out.println(values);
}
}
[Java, is, useful]
當「向陣列新增」指的是保持現有的順序,並將另一個值放在最後一個值之後時,這是最接近的集合選擇。串列可以隨著值的增加而增長,add() 不需要呼叫方為每個新值分配並重新指派一個更大的陣列。當長度是資料形態的一部分,或其他 API 要求固定長度時,選擇固定陣列;當值的數量可以變化並希望在末尾附加時,選擇串列。
使用自訂方法向 Java 陣列附加
自訂的 push() 方法可以回傳一個包含原始元素和新值的更長陣列。呼叫方必須指派這個回傳的陣列,因為 Java 陣列不能就地增長。複製所需的時間與現有元素的數量成正比,並且需要為新陣列提供記憶體。
public class ArrayAppendExample {
private static String[] push(String[] array, String value) {
String[] longer = new String[array.length + 1];
System.arraycopy(array, 0, longer, 0, array.length);
longer[array.length] = value;
return longer;
}
public static void main(String[] args) {
String[] values = {"a", "b", "c"};
values = push(values, "d");
System.out.println(java.util.Arrays.toString(values));
}
}
[a, b, c, d]
回傳的參照很重要:原始陣列仍然保持原始長度,而 push() 建立並回傳一個單獨的陣列。指派該結果後,後續讀取將使用更長的陣列;忽略回傳值則會使呼叫方繼續使用原始陣列。當方法簽名或函式庫要求使用陣列時,這種方法很有用。重複該操作每次都會複製已有的元素,因此對於一系列的新增操作,使用可調整大小的集合通常更簡單,也避免了自己編寫這段複製邏輯。
使用 ArrayDeque.push() 作爲堆疊
對於新的堆疊程式碼,ArrayDeque 是一個可調整大小的雙端佇列,支援在任一端插入和刪除。它的 push() 方法在最前面新增,pop() 從同一端移除,從而實現後進先出的行爲。迭代雙端佇列時從最前面開始。
import java.util.ArrayDeque;
public class ArrayDequeExample {
public static void main(String[] args) {
ArrayDeque<String> values = new ArrayDeque<>();
values.push("Java");
values.push("is");
values.push("useful");
System.out.println("Top: " + values.peek());
System.out.println("Removed: " + values.pop());
System.out.println("Deque: " + values);
}
}
Top: useful
Removed: useful
Deque: [is, Java]
對於堆疊行爲,ArrayDeque.push() 提供了與 Stack.push() 展示的相同的頂部優先模型,同時雙端佇列也支援在其另一端進行操作。當你需要堆疊並且希望使用雙端佇列集合時使用它;當所需結果是一個將新元素放在末尾的有序串列時,使用 ArrayList.add()。這一選擇取決於值應該放在哪裡以及它們將如何被取用,而不是 Java 陣列是否擁有內建的 push 操作。