Javaの配列:リファレンスガイド

Javaの配列:リファレンスガイド

1. 前書き

このチュートリアルでは、Java言語のコアコンセプトである配列について詳しく説明します。

最初に配列とは何か、次にそれらの使用方法を確認します。全体として、次の方法について説明します。

  • 配列を使い始める

  • 配列要素の読み取りと書き込み

  • 配列をループする

  • 配列をListStreamsなどの他のオブジェクトに変換します

  • 配列の並べ替え、検索、結合

2. アレイとは?

まず最初に、配列とは何かを定義する必要がありますか? the Java documentationによると、配列はan object containing a fixed number of values of the same typeです。 配列の要素にはインデックスが付けられています。つまり、番号(indicesと呼ばれる)で要素にアクセスできます。

配列はセルの番号付きリストと見なすことができ、各セルは値を保持する変数です。 Javaでは、番号付けは0から始まります。

プリミティブ型の配列とオブジェクト型の配列があります。 これは、int, float, boolean, …の配列だけでなく、String, Objectの配列やカスタムタイプも使用できることを意味します。

3. 配列のセットアップ

配列が明確に定義されたので、その使用法について詳しく見ていきましょう。

配列の使用方法を教える多くのトピックを取り上げます。 配列の宣言と初期化の方法など、いくつかの基本を学びますが、配列の並べ替えや検索など、より高度なテーマについても説明します。

まず、宣言と初期化から始めましょう。

3.1. 宣言

宣言から始めましょう。 Javaで配列を宣言するには、2つの方法があります。

int[] anArray;

or:

int anOtherArray[];

The former is more widely used than the latter

3.2. 初期化

次に、配列を初期化する方法を確認します。 ここでも、配列を初期化する方法は複数あります。 ここで主なものを確認しますが、this articleは配列の初期化について詳しく説明しています。

簡単な方法から始めましょう:

int[] anArray = new int[10];

このメソッドを使用して、10個のint要素の配列を初期化しました。 配列のサイズを指定する必要があることに注意してください。

このメソッド、we initialize each element to its default value、ここでは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]);

インデックスを使用して配列セルにアクセスする方法に注意してください。 The number between the brackets is the specific position of the array we want to access.

セルにアクセスするときに、渡されたインデックスが負であるか、最後のセルを超えている場合、JavaはArrayIndexOutOfBoundExceptionをスローします。

次に、not to use a negative index, or an index greater than or equal to the array sizeに注意する必要があります。

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の数字がコンソールに出力されます。 As we can see we made use of the length property. This is a public property giving us the size of the array.

もちろん、whiledo whileなどの他のループメカニズムを使用することもできます。 ただし、Javaコレクションの場合、foreachループを使用して配列をループすることができます。

int[] anArray = new int[] {1, 2, 3, 4, 5};
for (int element : anArray) {
    System.out.println(element);
}

この例は前の例と同等ですが、インデックスの定型コードを削除しました。 The foreach loop is an option when:

  • 配列を変更する必要はありません(要素に別の値を入力しても、配列内の要素は変更されません)

  • 他のことをするのにインデックスは必要ありません

6. バラールス

配列の作成と操作に関する基本については、すでに説明しました。 次に、varargsから始めて、より高度なトピックについて詳しく説明します。 注意として、varargsは、メソッドに任意の数の引数を渡すために使用されます。

void varargsMethod(String... varargs) {}

このメソッドは、0から任意の数のString引数を取ることができます。 varargsに関する記事は、hereにあります。

ここで知っておく必要があるのは、メソッド本体の内部で、varargsパラメータが配列に変わることです。 しかし、we can also pass an array directly as the argument.上記で宣言されたサンプルメソッドを再利用して、その方法を見てみましょう。

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 aList = new ArrayList<>();
for (int element : anArray) {
    aList.add(element);
}

しかし、もう少し簡潔な方法があります。

Integer[] anArray = new Integer[] {1, 2, 3, 4, 5};
List aList = Arrays.asList(anArray);

The static method Arrays.asList takes a varargs argument and creates a list with the passed values.残念ながら、この方法にはいくつかの欠点があります。

  • プリミティブ型の配列を使用することはできません

  • UnsupportedOperationExceptionがスローされるため、作成したリストに要素を追加したり、リストから要素を削除したりすることはできません。

8. 配列からストリームへ

これで配列をリストに変換できますが、Java 8以降はStream APIにアクセスできるため、配列をStreamに変換したい場合があります。 Javaは、そのためのArrays.streamメソッドを提供します。

String[] anArray = new String[] {"Milk", "Tomato", "Chips"};
Stream aStream = Arrays.stream(anArray);

Object配列をメソッドに渡すと、一致するタイプのStreamが返されます(例: Integerの配列の場合はStream<Integer>)。 プリミティブを渡すと、対応するプリミティブStreamが返されます。

アレイのサブセットでのみストリームを作成することもできます。

Stream anotherStream = Arrays.stream(anArray, 1, 3);

これにより、「トマト」と「チップ」StringsのみでStream<String> が作成されます(最初のインデックスは包括的で、2番目のインデックスは排他的です)。

9. 配列の並べ替え

次に、配列を並べ替える方法、つまり要素を特定の順序で並べ替える方法を見てみましょう。 The Arrays class provides us with the sort method.streamメソッドと少し似ていますが、sortには多くのオーバーロードがあります。

ソートするオーバーロードがあります:

  • プリミティブ型配列:昇順で並べ替えられます

  • Object配列(これらのObjectComparableインターフェースを実装する必要があります):自然な順序に従って並べ替えられます(Comparable)compareToメソッドに依存します)

  • ジェネリック配列:指定されたComparatorに従って並べ替えられます

さらに、配列の特定の部分のみを並べ替えることができます(開始インデックスと終了インデックスをメソッドに渡します)。

sortメソッドの背後にあるアルゴリズムは、プリミティブ配列とその他の配列のそれぞれquick sortmerge 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で見つけました。

If we have a sorted array though, we can use another solution: the binary search.二分探索の原理はthis articleで説明されています。

Fortunately, Java provides us with the Arrays.binarySearch method.検索する配列と要素を指定する必要があります。

ジェネリック配列の場合は、最初に配列を並べ替えるために使用された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つの配列を連結する方法を見てみましょう。 The idea is to create an array which length is the sum of the two arrays to concatenate.その後、add the elements of the first one and then the elements of the second oneを実行する必要があります。

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。 このメソッドは、ソースarray、ソース位置、宛先array、宛先位置、およびコピーする要素の数を定義するint を取ります。

System.arraycopy(anArray, 0, resultArray, 0, anArray.length);
System.arraycopy(anotherArray, 0, resultArray, anArray.length, anotherArray.length);

ご覧のとおり、最初の配列をコピーしてから、2番目の配列(最初の配列の最後の要素の後)をコピーします。

12. 結論

この詳細な記事では、Javaでの配列の基本的な使用法といくつかの高度な使用法について説明しました。

Javaには、Arrays utility classを介して配列を処理するための多くのメソッドが用意されていることがわかりました。 Apache CommonsGuavaなどのライブラリ内の配列を操作するためのユーティリティクラスもあります。

この記事の完全なコードはour GitHubにあります。