このチュートリアルでは、Javaの固定長配列の扱い方について学習します。
Javaでは、配列はメモリの連続したブロックに格納されている要素の集まりです。配列は固定サイズのデータ構造で、保持できる要素の数は決まっています。一度作成した配列のサイズを変更することはできません。
配列の要素は連続したメモリブロックに格納され、各要素はインデックスを使用してアクセスされます。Javaで配列を宣言するには、次のような構文を用います。
dataType[] arrayName
配列を作成してメモリを確保するには、new演算子の後に、型と確保したい要素数を指定します。[]演算子はデータが配列であることをコンパイラに伝えます。
初期値が設定されない場合、各データ型ごとのデフォルト値で初期化されます。int型の場合は、デフォルト値として0が与えられます。参照型の場合はnullで初期化されます。
例えば、int型の5個の要素を持つ整数の配列を作成してみましょう。この例では、配列numbersを作成し、その要素数を5に設定しています。この配列には、0から4までのインデックスを持つ5個の要素があります。
int[] numbers = new int[5];
配列を初期化した後はインデックス演算子を使って、要素の値を更新できます。Stringオブジェクトとは異なり、配列は可変オブジェクトであるため、初期化後に値を変更することができます。可変オブジェクトに変更を加えたとき、新しいオブジェクトは生成されず、既存のオブジェクトの値が変更されます。
numbers[0] = 3;
numbers[1] = 5;
6番目の要素のデータを割り当てることは、もはや追跡されないデータをメモリに挿入することを意味します。java.lang.ArrayIndexOutOfBoundsExceptionというエラーが発生します。
また、配列の作成時に、値のリストで配列を初期化することもできます。
int[] numbers = new int[] {20,13,-12,2,5};
Javaにおけるlengthプロパティは、配列の要素数を表します。例えば、長さが5の配列があれば、5個の要素を保持できることを意味します。このプロパティは、与えられた配列に対して固定されており、変更することはできません。このプロパティは、通常、配列名の後にドット(.)を付け、arrayName.lengthのようにキーワードlengthを使用してアクセスします。
lengthを使って配列の全要素を繰り返し処理してみましょう。
class Main {
public static void printIntArray(int[] intArr) {
for(int i = 0; i < intArr.length; i++){
System.out.println(intArr[i]);
}
}
public static void main(String[] args) {
int[] numbers = new int[5];
printIntArray(array);
// 値の更新
for(int i = 0; i < numbers.length; i++){
numbers[i] = i;
}
printIntArray(numbers);
printIntArray(numbers.length);
}
}
他の例も見てみましょう。
class Main {
public static void printIntArray(int[] intArr) {
for(int i = 0; i < intArr.length; i++){
System.out.println(intArr[i]);
}
}
public static void main(String[] args) {
int[] arr = new int[]{20,13,-12,2,5};
printIntArray(arr);
// []演算子で指定の要素にアクセスすることができます
arr[3] = 34;
arr[1] = 40;
printIntArray(arr);
// 6番目の要素のデータを割り当てることは、もはや追跡されないデータをメモリに挿入することを意味します
// java.lang.ArrayIndexOutOfBoundsExceptionというエラーが発生します
// arr[5] = 3;
}
}
Javaでは、固定長配列は一度、配列を宣言し、一定の大きさで初期化すると、配列の大きさを変更することはできません。
配列の要素を増やすには、より大きなサイズの新しい配列を作成し、古い配列から新しい配列に要素をコピーし、新しい配列を古い配列の変数に代入できます。しかし、これは特に頻繁に行う必要がある場合、非効率になることがあります。
class Main {
public static void printIntArray(int[] intArr) {
for(int i = 0; i < intArr.length; i++){
System.out.println(intArr[i]);
}
}
public static void main(String[] args) {
int[] arr = new int[]{20,13};
// 固定配列は宣言後にサイズを変更することができません
// 解決策として、新しい容量 = 論理サイズ × d となるように、より大きな容量の新しい配列を作成します。
// 新しい容量が2倍になるよう成長係数dを設定します
int[] newArr = new int[arr.length * 2];
// arr の内容を newArrにコピーします。これには O(n)の時間がかかります
for(int i = 0; i < arr.length; i++){
newArr[i] = arr[i];
}
System.out.println("Printing the new copied array");
printIntArray(newArr);
// newArrに要素を追加していきます
newArr[2] = 3;
newArr[3] = 15;
printIntArray(newArr);
}
}
配列に頻繁に要素を追加したり削除したりする必要があり、配列のサイズを気にかけたくない場合は、Java Collections Frameworkの一部であるArrayListというクラスを使用することができます。ArrayListはサイズ変更可能な動的配列で、要素の追加と削除をより簡単に行うことができます。
次の記事では、配列の操作を可能にするArraysクラスについて解説します。
配列については、CS基礎/中級/リストで詳しく学習できます。