Arraysクラス

Java Arraysクラス

Javaでは、配列はすべて同じデータ型の要素の集まりでした。配列は、複数の値を1つの変数に格納するために使用されるオブジェクトです。

Arraysクラスは、Java Standard Edition(SE)の一部であるjava.utilパッケージに属し、配列を操作する(ソートや検索など)ためのさまざまなメソッドを含むユーティリティクラスです。ユーティリティクラスとは、java.lang.Mathなど、staticなメソッドと変数だけが含まれているクラスのことで、特定の処理を実行するためのメソッドを集めたクラスを指します。

ユーティリティクラスは通常、静的メソッドとして使用するように設計されています。つまり、クラスのインスタンスを生成することなく呼び出すことができます。Arraysクラスは、int, double, charなどのプリミティブなデータ型と、オブジェクトの配列に対してオーバーロードされたメソッドのセットを提供します。これにより、データ型ごとに別々のメソッドを記述することなく、同じメソッドで異なるデータ型の配列を操作することができます。

java.utilパッケージのArraysクラスは、配列を操作するためのさまざまなメソッドを提供します。例えば、2つの配列が等しいかどうかを比較したり、配列をソートしたり、配列に対する操作をいくつも提供しています。

Java Arraysクラスで配列をソートする

それでは配列をソートしてみます。Arraysクラスのsortメソッドについて見てみましょう。int型などプリミティブ型の配列のソートにはデュアルピボットクイックソートが、Stringなどオブジェクトの配列のソートには安定なソートであるTimSortが使用されます。

// Arraysクラスのimport
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] numbers = {34,2,11,23,0};
        Arrays.sort(numbers);

        for (int number : numbers) {
            System.out.println(number);
        }

        String[] names = {"Steve","Alice","Ema","Jack"};
        Arrays.sort(names);
        for (String name : names) {
            System.out.println(name);
        }
    }
}

Java Arraysクラスで配列の要素の等価性をチェック

Arraysクラスのequalsメソッドは、配列を比較するためのstaticメソッドです。名前は同じですが、Objectクラスのequalsメソッドをオーバーライドしたものではなく、配列の型ごとにオーバーロードされています。

Arraysクラスのequalsメソッドを使うと、2つの配列が等しいかどうかを比較することができます。equalsメソッドは,2つの配列を引数として受け取り、2つの配列が等しい場合はtrueを、等しくない場合はfalseを返します。

equalsメソッドを使用する場合、配列の要素の順序は重要です。同じ要素を同じ順番で持っている場合、等しいとみなされ、要素の順番が異なる場合、等しいとはみなされません。それでは例を見てみましょう。

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] arr1 = {1,2,3,4,5};
        int[] arr2 = {1,2,3,4,5};
        int[] arr3 = {5,4,3,2,1};

        System.out.println(Arrays.equals(arr1, arr2));
        System.out.println(Arrays.equals(arr1, arr3));
    }
}

Java Arraysクラスで配列の出力

JavaでSystem.out.printlnメソッドを使って配列を出力すると、通常、配列のデータ型とハッシュコードが出力されます。

int[] numbers = {1,2,3,4,5};
System.out.println(numbers); // [I@d716361

出力は、[Iという接頭辞で示される配列のデータ型から始まります。Iはintを表し,配列が整数の配列であることを示しています。@記号の後には16進数のハッシュコードが続きます。これはオブジェクトごとの識別ハッシュコードで、メモリアドレスそのものではありません。

このデフォルトの出力は、配列の内容を出力するにはあまり便利ではありません。配列の内容を表示するには、次のようにArraysクラスのtoStringメソッドを使用することができます。

JavaにおけるtoStringメソッドは、Javaのクラス階層のルートであるObjectクラスで定義されているメソッドです。すべてのJavaクラスで継承され、オブジェクトを文字列表現に変換するために使用されます。

ObjectクラスのtoStringメソッドのデフォルトの実装は、オブジェクトの文字列表現をclassname@hashcodeの形で返します。たとえば、以下のようになります。

Object obj = new Object();
System.out.println(obj.toString()); // java.lang.Object@6ff3c5b5

しかし、JavaのほとんどのクラスはtoStringメソッドをオーバーライドして、より意味のあるオブジェクトの文字列表現を提供します。配列はtoStringメソッドをオーバーライドしていないため、代わりにArraysクラスのstaticメソッドであるtoStringを配列に使用してみましょう。

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] numbers = {1,2,3,4,5};
        System.out.println(numbers);
        System.out.println(Arrays.toString(numbers));

        String[] names = {"Steve","Alice","Ema"};
        System.out.println(names);
        System.out.println(Arrays.toString(names));
    }
}

Java Arraysクラスで配列を特定の値で埋める

Arraysクラスのfillメソッドは、配列に与えられた値を埋めるために使用されるメソッドです。以下のような形で利用可能です。

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        boolean[] flags = new boolean[5];
        Arrays.fill(flags, false);
        System.out.println(Arrays.toString(flags));
    }
}

Java Arraysクラスで配列をコピーする

ArraysクラスのcopyOfメソッドは、配列のコピーを作成するために使用されるメソッドです。これらのメソッドは、それぞれ指定した配列のコピーを作成し、そのコピーを新しい配列として返します。copyOfメソッドはコピー元の配列と、新しい配列の長さを引数として受け取ります。

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] numbers = {1,2,3,4,5};
        int[] copy = Arrays.copyOf(numbers, numbers.length);
        System.out.println(Arrays.toString(copy));
    }
}

copyOfメソッドは、配列のシャローコピーを作成します。新しい配列が作られ、元の配列の要素の値がそのままコピーされます。そのため、コピーの要素に別の値を代入しても元の配列には反映されません。ただし、要素が参照型の場合にコピーされるのは参照だけなので、要素が指すオブジェクトはコピー元とコピー先で共有されます。

import java.util.Arrays;

public class Main {
   public static void main(String[] args) {
      int[] numbers = {1,2,3};
      int[] copy = Arrays.copyOf(numbers, numbers.length);

      copy[0] = 0; // 新しい配列の要素の値を変更
      // 元の配列へ反映されない
      System.out.println(Arrays.toString(numbers));
      System.out.println(Arrays.toString(copy));
   }
}

新しい長さが元の配列の長さよりも長い場合、新しい配列の足りない分の要素は、要素の型のデフォルト値(例えば、整数の場合は0、booleanの場合はfalseなど)で埋められます。新しい長さが元の配列の長さよりも短い場合は、新しい配列には元の配列の最初のN個の要素が含まれます(Nは新しい長さ)

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] numbers = {1,2,3};
        int[] copy1 = Arrays.copyOf(numbers,1);
        int[] copy2 = Arrays.copyOf(numbers,10);

        System.out.println(Arrays.toString(copy1));
        System.out.println(Arrays.toString(copy2));
    }
}

配列の使い方は初級コースの「配列」で、メモリ上での仕組みは中級コースの「固定長配列」と「動的配列」で詳しく学べます。

この記事を書いた人

著者の画像

Jeffry Alvarado

Ex-Facebook Engineer 大学ではコンピュータサイエンスを専攻し、在学中に複数のインターンシップを経験。コンピュータサイエンスが学習できるプラットフォームRecursionを創業し、CTOとしてカリキュラム作成、ソフトウェア開発を担当。