Java
 Computer >> コンピューター >  >> プログラミング >> Java

【Java 9】Arraysクラスに追加された新メソッド「equals」「compare」「mismatch」の使い方

JavaのArraysクラスには、配列を操作するためのさまざまなメソッドが用意されており、配列をリストとして扱えるようにする静的ファクトリメソッドも含まれています。Java 9では、このArraysクラスに次の3つの重要なメソッドが新たに追加されました。

  • Arrays.equals() … 指定範囲の配列同士が等しいかどうかを判定
  • Arrays.compare() … 指定範囲の配列同士を辞書式順序で比較
  • Arrays.mismatch() … 2つの配列間で最初に不一致となるインデックスを検出

いずれのメソッドも、配列全体だけでなくfromIndex / toIndexによる範囲指定(スライス比較)に対応しているのが大きな特徴です。

Arrays.equals()メソッド

Java 9では、従来のequals()メソッドに複数のオーバーロードが追加されました。新しいメソッドは、2つの配列それぞれに対してfromIndextoIndexを受け取り、相対的なインデックス位置に基づいて、指定範囲内の要素が等しいかどうかを判定します。

構文

public static boolean equals(int[] a, int aFromIndex, int aToIndex,
                             int[] b, int bFromIndex, int bToIndex)

上記の構文では、指定された範囲内の2つのint型配列が等しい場合にtrueを返します。int型以外にも、char型やlong型など各プリミティブ型、Object型に対しても同様のオーバーロードが用意されています。

サンプルコード

import java.util.Arrays;

public class CompareArrayTest {
    public static void arrayEqualsTest() {
        int[] existRows = {0, 1, 2, 3, 4, 5};
        int[] newRows = {3, 4, 5, 1, 2, 0};
        System.out.println(Arrays.equals(existRows, newRows));
        System.out.println(Arrays.equals(existRows, 1, 3, newRows, 3, 5));
        System.out.println(Arrays.equals(existRows, 3, 5, newRows, 0, 2));
    }

    public static void main(String args[]) {
        CompareArrayTest.arrayEqualsTest();
    }
}

実行結果

false
true
true

1行目は配列全体を比較しているため、要素の並び順が異なりfalseとなります。一方、2行目・3行目は範囲を指定して比較しており、たとえばexistRowsのインデックス1〜2({1, 2})とnewRowsのインデックス3〜4({1, 2})は一致するためtrueが返されます。

Arrays.compare()メソッド

Java 9では、compare()メソッドにもfromIndex / toIndexパラメータを持つオーバーロードが追加されました。これにより、配列の一部分(スライス)同士を辞書式順序(lexicographical order)で比較できるようになっています。

構文

public static int compare(int[] a, int aFromIndex, int aToIndex,
                          int[] b, int bFromIndex, int bToIndex)

このメソッドは、指定された範囲内の2つのint型配列を辞書式順序で比較し、aがbより小さい場合は負の値、等しい場合は0、大きい場合は正の値を返します。

サンプルコード

import java.util.Arrays;

public class LexicographicalArraysTest {
    public static void main(String args[]) {
        LexicographicalArraysTest.compareSliceArraysTest();
    }

    public static void compareSliceArraysTest() {
        int[] tomMarks = {5, 6, 7, 8, 9, 10};
        int[] daisyMarks = {5, 6, 7, 10, 9, 10};
        int[] maryMarks = {5, 6, 7, 8};
        System.out.println(Arrays.compare(tomMarks, 0, 3, daisyMarks, 0, 3));
        System.out.println(Arrays.compare(tomMarks, 0, 4, maryMarks, 0, maryMarks.length));
        System.out.println(Arrays.compare(daisyMarks, 0, 4, maryMarks, 0, maryMarks.length));
    }
}

実行結果

0
0
1

1行目・2行目は比較対象の範囲が完全に一致しているため0が返ります。3行目では、{5, 6, 7, 10}と{5, 6, 7, 8}を比較しており、最初に異なる要素(10と8)の大小関係により1(正の値)が返されます。

Arrays.mismatch()メソッド

Java 9では、mismatch()メソッドのオーバーロードも追加されました。このメソッドを使うと、2つの配列(またはその範囲)の間で最初に一致しない要素の相対インデックスを見つけて返すことができます。

構文

public static int mismatch(int[] a, int aFromIndex, int aToIndex,
                           int[] b, int bFromIndex, int bToIndex)

このメソッドは、指定された範囲内で最初に不一致となった要素の相対インデックスを返します。不一致が見つからない場合は-1を返します。戻り値のインデックスは、0(含む)から小さい方の範囲の長さ(含む)までの範囲内の値になります。

サンプルコード

import java.util.Arrays;

public class MismatchMethodTest {
    public static void main(String[] args) {
        MismatchMethodTest.mismatchArraysTest();
    }

    public static void mismatchArraysTest() {
        int[] a = {1, 2, 3, 4, 5};
        int[] b = {1, 2, 3, 4, 5};
        int[] c = {1, 2, 4, 4, 5, 6};
        System.out.println(Arrays.mismatch(a, b));
        System.out.println(Arrays.mismatch(a, c));
        System.out.println(Arrays.mismatch(a, 0, 2, c, 0, 2));
        System.out.println(Arrays.mismatch(a, 0, 3, c, 0, 3));
        System.out.println(Arrays.mismatch(a, 2, a.length, c, 2, 5));
    }
}

実行結果

-1
2
-1
2
0

1行目は配列aとbが完全に一致しているため-1です。2行目は3番目の要素(3と4)が異なるため、インデックス2が返ります。4行目のように範囲を絞って比較すると、範囲内での相対的な不一致位置が返される点にも注目してください。

まとめ

Java 9でArraysクラスに追加されたequals()compare()mismatch()の3つのメソッドを使えば、配列全体だけでなく任意の範囲(スライス)を対象とした等価判定・辞書式比較・不一致箇所の特定が簡単に行えます。部分配列の比較処理を自前で実装する必要がなくなるため、コードの可読性と信頼性が向上する便利な機能です。

  1. Java 9におけるクラスローダーの変更点を徹底解説

    すべてのJavaプログラムはJava仮想マシン(JVM)上で実行されます。コンパイル後、Javaのクラスはプラットフォームやマシンに依存しないバイトコードへと変換され、.classファイルとして保存されます。クラスを使用する際には、ClassLoader(クラスローダー)がそのクラスをメモリに読み込みます。クラスは名前によって参照された時点でJava環境に導入され、クラスの実行開始時にクラスローダーによるロードが行われます。main()メソッドは、そのクラスを起動するためのエントリーポイントです。Java 9では、このクラスローダーに関していくつかの重要な変更が加えられました。以下に主な変更点

  2. Java 9における@Deprecatedアノテーションの改善点とは?新要素「since」「forRemoval」を徹底解説

    @Deprecatedアノテーションとはクラス、メソッド、フィールドなど、プログラム内のあらゆる要素に付与できる@Deprecatedアノテーションは、「その要素はもはや使用すべきではない」ことを示すためのものです。要素が非推奨とされる主な理由は以下の通りです。使用すると危険であり、エラーを引き起こす可能性がある将来のバージョンで互換性がなくなる可能性がある将来のバージョンで削除される可能性があるより優れた、効率的な代替手段がすでに提供されているJava 9で追加された2つの新しい要素Java 9では、@DeprecatedアノテーションにsinceとforRemovalという2つの新しい属性