HOWTO · Java
在 Java 中對陣列進行切片
本文將幫助你用 Java 將陣列切片為子陣列。
本頁內容
要對 Java 陣列進行切片,可以把一個連續範圍內的元素複製到一個新陣列中。下面的範例使用左閉右開的範圍:fromIndex 包含在內,toIndex 是第一個不包含在內的索引。例如,範圍 [2, 5) 選取的是索引 2、3 和 4。原始陣列保持不變。
在 Java 中通過複製元素對陣列進行切片
用迴圈可以讓索引的對應關係一目了然。先分配長度為 toIndex - fromIndex 的結果陣列,然後把每個選中的值複製到結果陣列中對應的位置。
下面這個完整的程式從一個整數陣列中選取索引 1 到 3 的元素:
import java.util.Arrays;
public class ArraySliceLoop {
static int[] slice(int[] values, int fromIndex, int toIndex) {
int[] result = new int[toIndex - fromIndex];
for (int i = 0; i < result.length; i++) {
result[i] = values[fromIndex + i];
}
return result;
}
public static void main(String[] args) {
int[] values = {10, 20, 30, 40, 50};
int[] part = slice(values, 1, 4);
System.out.println(Arrays.toString(part));
}
}
結果是一個獨立的陣列。迴圈計數器 i 針對結果陣列從零開始,而 fromIndex + i 則定位來源陣列中對應的元素。呼叫該方法時,應傳入在來源陣列範圍內描述有效範圍的索引。
在 Java 中使用 copyOfRange() 方法對陣列進行切片
Arrays.copyOfRange() 提供了一種從某個範圍直接建立新陣列的方法。該方法屬於 java.util.Arrays;它的 from 參數包含在內,to 參數不包含在內。確切的 API 名稱中包含 copyOfRange()。
下面這個程式複製索引 1、2 和 3 的元素:
import java.util.Arrays;
public class ArraySliceCopyOfRange {
public static void main(String[] args) {
int[] values = {10, 20, 30, 40, 50};
int[] part = Arrays.copyOfRange(values, 1, 4);
System.out.println(Arrays.toString(part));
}
}
返回的陣列包含選中的值,修改它不會替換原始陣列中的元素。對於 int[] 等基本型別陣列,複製的是值本身。對於物件陣列,陣列是新建的,但其中的元素仍是對相同物件的參照。
在 Java 中使用流對陣列進行切片
流可以通過把索引流對應回來源陣列來選取陣列中的值。把這種方式當作一種可選方案:只有當專案設定的 Java 執行環境支援所需的流 API 時才使用它。這裡不預設任何執行環境版本。
這個操作可以寫成 IntStream.range(fromIndex, toIndex).map(i -> values[i]).toArray()。IntStream.range 使用包含起始、排除結尾的約定,因此與其他方法遵循相同的範圍約定。這個精簡的表達式只是一個示意;在實際使用之前,請先對照專案宣告的 Java 執行環境確認 API 可用性。當執行環境未知時,迴圈或 Arrays.copyOfRange() 是直接明瞭的替代方案。
在 Java 中使用 System.arraycopy 方法對陣列進行切片
System.arraycopy 把指定數量的元素從一個陣列複製到另一個陣列。先建立一個長度為 toIndex - fromIndex 的目標陣列,然後傳入來源位置、目標位置和要複製的元素數量。
import java.util.Arrays;
public class ArraySliceSystemArraycopy {
public static void main(String[] args) {
int[] values = {10, 20, 30, 40, 50};
int fromIndex = 1;
int toIndex = 4;
int[] part = new int[toIndex - fromIndex];
System.arraycopy(values, fromIndex, part, 0, part.length);
System.out.println(Arrays.toString(part));
}
}
這些參數依序是來源陣列、來源位置、目標陣列、目標位置和要複製的元素數量。這裡目標位置為零,因此選中的來源範圍會從目標陣列的第一個位置開始填滿 part。來源陣列和目標陣列的元素型別必須相容,位置和長度也必須同時適合兩個陣列。
在 Java 中使用 asList 和 subList 對陣列進行切片
對於參照型別陣列,Arrays.asList() 會建立一個由該陣列支撐的固定大小清單。subList(fromIndex, toIndex) 返回所選清單範圍的檢視。當結果應當是一個獨立陣列時,把該檢視轉換成陣列。
import java.util.Arrays;
import java.util.List;
public class ArraySliceSubList {
public static void main(String[] args) {
String[] values = {"red", "green", "blue", "gold"};
List<String> list = Arrays.asList(values);
List<String> selected = list.subList(1, 3);
String[] part = selected.toArray(new String[0]);
System.out.println(Arrays.toString(part));
}
}
Arrays.asList() 返回的清單大小固定:你可以替換某個元素,但不能添加或刪除清單條目。子清單是與該清單綁定的檢視。呼叫 toArray() 會建立一個獨立的陣列,儘管物件元素本身仍是對相同物件的參照。這種方式適用於 String[] 等參照型別陣列;基本型別陣列需要使用上面展示的迴圈、copyOfRange() 或 System.arraycopy 等處理基本型別陣列的方法。
結論
當你想看清或自訂逐元素複製的過程時,使用迴圈。想要直接複製陣列時選擇 Arrays.copyOfRange(),或者在需要指定目標位置和複製長度時選擇 System.arraycopy。當專案的 Java 執行環境支援所需的 API 時,流提供了基於索引的選取方式。對於參照型別陣列,asList 和 subList 提供了清單檢視;呼叫 toArray() 即可獲得一個獨立的結果陣列。