Javaの配列:リファレンスガイド
1.はじめに
このチュートリアルでは、Java言語の中心的な概念である配列について詳しく説明します。
まず配列とは何か、次にそれらの使い方を見ていきましょう。全体として、次の方法について説明します。
-
配列を始めよう
-
配列要素を読み書きする
-
配列をループする
-
配列を
List
や
Streams
のような他のオブジェクトに変換する -
配列のソート、検索、結合
2.配列とは何ですか?
まず最初に、配列を定義する必要がありますか。
Javaのドキュメント
によると、配列は
同じ型の固定数の値を含むオブジェクトです
。配列の要素にはインデックスが付けられています。つまり、番号でアクセスできます(
indices
と呼びます)。
配列はセルの番号付きリストと見なすことができ、各セルは値を保持する変数です。 Javaでは、番号付けは0から始まります。
プリミティブ型配列とオブジェクト型配列があります。これは、
int、float、boolean、…
の配列を使用できることを意味しますが、
String、Object
、およびカスタム型の配列も使用できます。
3.配列を設定する
配列が明確に定義されたので、その用途に飛び込みましょう。
配列の使い方を私たちに教える多くのトピックをカバーします。配列を宣言して初期化する方法など、基本的なことは学びますが、配列の並べ替えや検索など、より高度なトピックについても説明します。
宣言と初期化から始めましょう。
3.1. 宣言
宣言から始めましょう。 Javaで配列を宣言する方法は2つあります。
int[]anArray;
または
int anOtherArray[];
-
前者は後者よりも広く使われています** 。
3.2. 初期化
配列を初期化する方法を見てみましょう。配列を初期化する方法は複数あります。ここに主なものがありますが、https://www.baeldung.com/java-initialize-array[この記事]では配列の初期化について詳しく説明しています。
簡単な方法から始めましょう。
int[]anArray = new int[10];
このメソッドを使用して、10個の
int
要素の配列を初期化しました。
配列のサイズを指定する必要があることに注意してください。
このメソッドを使用するとき、
各要素をデフォルト値
、ここでは0
に初期化します。
Object
の配列を初期化するとき、要素はデフォルトで
null
です。
作成時に直接配列に値を設定する可能性を与える別の方法があります。
int[]anArray = new int[]{1, 2, 3, 4, 5};
ここでは、1から5までの数字を含む5要素の配列を初期化しました。
この方法を使用する場合、配列の長さを指定する必要はありません。それは、括弧内で宣言されている要素の数です。
4.要素へのアクセス
それでは、配列の要素にアクセスする方法を見てみましょう。これを実現するには、配列セルの位置を指定します。
たとえば、この小さなコードスニペットは10をコンソールに表示します。
anArray[0]= 10;
System.out.println(anArray[0]);
配列セルにアクセスするためにインデックスを使用していることに注意してください。括弧内の数字は、アクセスしたい配列の特定の位置です。
セルにアクセスするとき、渡されたインデックスが負の値であるか最後のセルを超える場合、Javaは
ArrayIndexOutOfBoundException
をスローします。
その場合、負のインデックス、または配列サイズ以上のインデックスを使用しないように注意してください。
5.配列を繰り返し処理する
要素に1つずつアクセスすることは便利ですが、配列を反復処理することをお勧めします。これを実現する方法を見てみましょう。
最初の方法は
for
ループを使うことです。
int[]anArray = new int[]{1, 2, 3, 4, 5};
for (int i = 0; i < anArray.length; i++) {
System.out.println(anArray[i]);
}
これにより、コンソールに1〜5の番号が表示されます。 ** ご覧のとおり、
length
プロパティを使用しました。これは配列のサイズを与えるパブリックプロパティです。
もちろん、
while
や
do while
のような他のループメカニズムを使うことも可能です。ただし、Javaコレクションの場合は、
foreach
ループを使用して配列をループ処理することができます。
int[]anArray = new int[]{1, 2, 3, 4, 5};
for (int element : anArray) {
System.out.println(element);
}
この例は前の例と同じですが、私たちはインデックスの定型コードを取り除きました。
foreach
ループは次の場合のオプションです。
-
配列を変更する必要はありません(要素に別の値を入れる
配列内の要素を変更しないでください)
** 他のことをするのに索引は必要ない
6.バラージ
配列の作成と操作に関しては、すでに基本について説明しました。それでは、
varargs
から始めて、より高度なトピックに飛び込みましょう。念のため、
varargs
は任意の数の引数をメソッドに渡すために使用されます。
void varargsMethod(String... varargs) {}
このメソッドは0から任意の数の
String
引数を取ることができます。
varargs
をカバーする記事はhttps://www.baeldung.com/java-varargs[こちら]にあります。
ここで知っておくべきことは、メソッド本体の内部で、
varargs
パラメータが配列に変わることです。しかし、
引数として配列を直接渡すこともできます
上記で宣言された例のメソッドを再利用することによってどのように見てみましょう:
String[]anArray = new String[]{"Milk", "Tomato", "Chips"};
varargsMethod(anArray);
と同じように動作します。
varargsMethod("Milk", "Tomato", "Chips");
7.配列をリストに変換する
配列は素晴らしいですが、
List
を扱うほうが便利なことがあります。ここでは、配列を
List
に変換する方法を説明します。
まず空のリストを作成し、その要素をリストに追加するために配列を反復処理することで、単純な方法で行います。
int[]anArray = new int[]{1, 2, 3, 4, 5};
List<Integer> aList = new ArrayList<>();
for (int element : anArray) {
aList.add(element);
}
しかし、もう少し簡潔な方法があります。
Integer[]anArray = new Integer[]{1, 2, 3, 4, 5};
List<Integer> aList = Arrays.asList(anArray);
-
静的メソッド
Arrays.asList
は
varargs
引数を取り、渡された値でリストを作成します。** 残念ながら、このメソッドにはいくつかの欠点があります。 -
プリミティブ型の配列を使うことはできません
-
作成したリストに要素を追加したり削除したりすることはできません。
UnsupportedOperationException
8.配列からストリームへ
配列をリストに変換できるようになりましたが、Java 8以降は
Stream API
にアクセスできるため、配列を
Stream
に変換したい場合があります。
Javaはhttps://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html#stream-double:A-[
Arrays.stream
]メソッドを提供しています。
String[]anArray = new String[]{"Milk", "Tomato", "Chips"};
Stream<String> aStream = Arrays.stream(anArray);
Object
配列をメソッドに渡すと、一致する型の
Stream
が返されます(例:
Integer
の配列の場合は
Stream <Integer>
)。
プリミティブを渡すと、対応するプリミティブ
Stream
を返します。
配列のサブセットにのみストリームを作成することもできます。
Stream<String> anotherStream = Arrays.stream(anArray, 1, 3);
これは、 “Tomato”と “Chips”
Strings
のみを持つ
__Stream <String>
__を作成します(最初のインデックスは包含的で、2番目のインデックスは排他的です)。
9.配列のソート
配列をソートする方法、つまり要素を特定の順序で並べ替える方法を見てみましょう。 **
Arrays
クラスはhttps://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html#sort-byte:A-[
sort
]メソッドを提供します。
stream
メソッド、
sort
にはたくさんのオーバーロードがあります。
並べ替えるには過負荷があります。
-
プリミティブ型配列:昇順で並べ替えられています
-
Object
配列(それらの
Object
は
Comparable
を実装する必要があります)
interface):自然順に従ってソートされています(に依存しています)
Comparable)
の
compareTo
メソッド
** ジェネリック配列:与えられた
Comparator
に従ってソートされます。
さらに、配列の特定の部分だけを並べ替えることもできます(開始インデックスと終了インデックスをメソッドに渡します)。
sort
メソッドの背後にあるアルゴリズムは、それぞれプリミティブ配列と他の配列のための
quick sort
と
merge sort
です。
いくつかの例を通して、これらすべてがどのように機能するかを見てみましょう。
int[]anArray = new int[]{5, 2, 1, 4, 8};
Arrays.sort(anArray);//anArray is now {1, 2, 4, 5, 8}
Integer[]anotherArray = new Integer[]{5, 2, 1, 4, 8};
Arrays.sort(anotherArray);//anotherArray is now {1, 2, 4, 5, 8}
String[]yetAnotherArray = new String[]{"A", "E", "Z", "B", "C"};
Arrays.sort(yetAnotherArray, 1, 3,
Comparator.comparing(String::toString).reversed());//yetAnotherArray is now {"A", "Z", "E", "B", "C"}
10.配列を検索する
配列の検索はとても簡単です。配列をループして、配列要素の中から要素を検索することができます。
int[]anArray = new int[]{5, 2, 1, 4, 8};
for (int i = 0; i < anArray.length; i++) {
if (anArray[i]== 4) {
System.out.println("Found at index " + i);
break;
}
}
ここで4番を検索してインデックス3で見つけました。
-
ソートされた配列がある場合は、別の解決策を使用することができます。バイナリサーチ
-
幸いなことに、Javaは
Arrays.binarySearch
メソッドを提供しています** 検索する配列と要素を指定する必要があります。
ジェネリック配列の場合は、最初に配列をソートするために使用された
Comparator
も指定する必要があります。配列のサブセットでメソッドを呼び出す可能性もあります。
バイナリ検索方法の使用例を見てみましょう。
int[]anArray = new int[]{1, 2, 3, 4, 5};
int index = Arrays.binarySearch(anArray, 4);
System.out.println("Found at index " + index);
4番目のセルに4を格納したので、結果としてインデックス3が返されます。すでに並べ替えられた配列を使用したことに注意してください。
11.連結配列
最後に、2つの配列を連結する方法を見てみましょう。 ** 長さが連結する2つの配列の合計である配列を作成するというアイデアです。
int[]anArray = new int[]{5, 2, 1, 4, 8};
int[]anotherArray = new int[]{10, 4, 9, 11, 2};
int[]resultArray = new int[anArray.length + anotherArray.length];
for (int i = 0; i < resultArray.length; i++) {
resultArray[i]= (i < anArray.length ? anArray[i]: anotherArray[i - anArray.length]);
}
ご覧のとおり、インデックスが最初の配列の長さよりまだ小さい場合は、その配列から要素を追加します。次に、2番目の要素から要素を追加します。ループを書かないように
Arrays.setAll
メソッドを利用することができます。
int[]anArray = new int[]{5, 2, 1, 4, 8};
int[]anotherArray = new int[]{10, 4, 9, 11, 2};
int[]resultArray = new int[anArray.length + anotherArray.length];
Arrays.setAll(resultArray, i -> (i < anArray.length ? anArray[i]: anotherArray[i - anArray.length]));
このメソッドは与えられた関数に従ってすべての配列要素を設定します。
この関数はインデックスと結果を関連付けます。
これは、配列にマージするための3番目のオプションです:
System.arraycopy
。このメソッドは、コピー元の
配列
、コピー元の位置、コピー先
配列
、コピー先の位置、コピーする要素の数を定義する
__int
__を取ります。
System.arraycopy(anArray, 0, resultArray, 0, anArray.length);
System.arraycopy(anotherArray, 0, resultArray, anArray.length, anotherArray.length);
ご覧のとおり、最初の配列をコピーし、次に2番目の配列(最初の配列の最後の要素の後)をコピーします。
12.結論
この詳細な記事では、Javaの配列の基本的な使い方と高度な使い方について説明しました。
私たちは、Javaがhttps://www.baeldung.com/java-util-arrays[
Arrays
ユーティリティクラス]を通して配列を扱うための多くのメソッドを提供することを見ました。
Apache Commons
やhttps://www.baeldung.com/guava-collections[Guava]などのライブラリ内の配列を操作するためのユーティリティクラスもあります。
この記事の全コードはhttps://github.com/eugenp/tutorials/tree/master/core-java-arrays[GitHub]にあります。