java配列


宣言

長さ指定は必須

int[] a; // 初期化しない
int[] a = new int[5]; // 0で初期化
int[][] a = new int[2][3]; // 二次元配列

初期化

初期化しない時、初期値0

int[] a = {1, 2, 3};  // 長さ3
int[][] a = {{1,2},{3,4}}; // 二次元の初期化
f(new int[]{1, 2, 3}); // 関数の引数として by @saka1029

長さ

  • 属性。関数ではない。
  • 長さは変更不可。
a.length
a[0].length // 二次元の場合

代入

  • 添え字 0 始まり
  • 最大添え字は length - 1
  • 超えると「java.lang.ArrayIndexOutOfBoundsException」例外投げられる
  • java.util.Arrays.fill(配列, 値) 指定値で配列全体を埋める
  • java.util.Arrays.fill(配列, 開始位置, 完了位置, 値) 指定値で配列一部を埋める
a[n];
a[i][j]; // 二次元の場合

追加、削除

  • 配列直接追加、削除は不可。代わりにコピーをご参考。

コピー

clone()とarraycopy()の例を見よう
import java.util.Arrays;

class Rec{
    String str;
    public Rec(String s){str=s;}
    public String toString(){return str;}
}
public class Main
{
    public static void main(String[] args) {
        int[] a = {1,2,3};
        int[] b = a.clone();
        a[1] = 7;
        System.out.println("a=" + Arrays.toString(a) + " b=" + Arrays.toString(b));

        String[] c = {"a", "b", "c"};
        String[] d = c.clone();
        c[1] = "7";
        System.out.println("c=" + Arrays.toString(c) + " d=" + Arrays.toString(d));

        Rec[] e = {new Rec("e"), new Rec("f"), new Rec("g")};
        Rec[] f = e.clone();
        Rec[] g = new Rec[3];
        Rec[] h = Arrays.copyOf(e, 5);
        Rec[] i = Arrays.copyOfRange(e, 2, 4);

        System.arraycopy(e, 0, g, 0, g.length);
        e[0] = new Rec("7");
        e[1].str ="8";
        g[2].str = "9";
        System.out.println("e=" + Arrays.toString(e) + " f=" + Arrays.toString(f) 
            + " g=" + Arrays.toString(g) + " h=" + Arrays.toString(h) + " i=" + Arrays.toString(i));
    }
}
実行結果
a=[1, 7, 3] b=[1, 2, 3]              <== b[1]は2のまま
c=[a, 7, c] d=[a, b, c]               <== d[1]はbのまま
e=[7, 8, 9] f=[e, 8, 9] g=[e, 8, 9] h=[e, 8, 9, null, null] i=[9, null]  <== f[0]はeのまま、f[1], g[1] は変わる、e[2],f[2],g[2]は変わる
各種コピーの異同
  • 各方法とも浅い(Shallow)コピー、つまりObjectの中身までコピーしてくれない。
  • clone(), copyOf(), copyOfRange()はコピー先をnewする手間は不要。
  • clone()は元と同じ配列を生成
  • copyOf()はコピー先の長さ可変。短くなると切断、長くなる分0、false、nullなどで補完。
  • copyOfRange()はコピー開始、終了位置(元配列の外でも可)可変。4/30追記:開始位置位置はマイナス不可、つまり前に追加不可、不便ですね。
  • arraycopy()は自分でコピー先を用意する手間かかるが、完全に自由
  • 自分メモ:arraycopy()が制約少ない割りに、便利さ僅かしか損なわれてない、いろいろ覚えるより、これ一本で行こう。

一部取り出し

  • System.arraycopy() 参考

ループ

for(int i=0; i<a.length; i++){
  // do sth. here
}

文字列化

  • java.util.Arrays.toString()    // 配列展開してくれる
  • java.util.Arrays.deepToString() // 多次元配列でも展開してくれる
import java.util.Arrays;

int[] a = {1,2,3};
System.out.prontln("a=" + Arrays.toString(a));

int[][][] j = {{{1,2},{3,4},{5,6}},{ {7,8},{9,10},{11,12}}};
System.out.println("j=" + j + " aj=" + Arrays.toString(j) + " deepJ=" + Arrays.deepToString(j));

出力

a=[1, 2, 3]  
j=[[[I@2a139a55 aj=[[[I@15db9742, [[I@6d06d69c] deepJ=[[[1, 2], [3, 4], [5, 6]], [[7, 8], [9, 10], [11, 12]]]

sort

  • java.util.Arrays .sort()
  • java.util.Arrays.parallelSort() 並列ソート

検索

  • java.util.Arrays.binarySearch() バイナリサーチ、事前にsort()が必須
  • 自分メモ:SortedMapを検討

型変換

  • java.util.Arrays.asList(配列) Listに変換

関連Class

上で紹介してない機能

  • java.util.Arrays
    • equals() / deepEquals()
    • hashCode / deepHashCode()
    • setAll() / parallelSetAll()
    • parallelPrefix()
    • spliterator()
    • stream()

参考

  1. https://www.sejuku.net/blog/14461