【備忘録】 配列に色々したときの挙動 in Java

20220427 追記

これは何

Java 17 において, 配列とか関数に色々したとき, どんな感じの挙動をするのかメモしたもの. 調べればそこらに出回ってる情報なので価値は低め.

shallow copy 1

コード

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
public static void main(String[] args) {
    PrintWriter out = new PrintWriter(System.out);
    int[]
        a = {0, 2, 4},
        b = a; // アドレスをコピーしている

    out.println("# 操作前");
    out.println(a[0] + " " + a[1] + " " + a[2]);
    out.println(b[0] + " " + b[1] + " " + b[2]);

    for(int i=0; i<a.length; i++)
        b[i]++;

    out.println("# 操作後");
    out.println(a[0] + " " + a[1] + " " + a[2]);
    out.println(b[0] + " " + b[1] + " " + b[2]);

    out.flush();
}

実行結果

1
2
3
4
5
6
# 操作前
0 2 4
0 2 4
# 操作後
1 3 5
1 3 5

shallow copy 2

コード

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public static void main(String[] args) {
    PrintWriter out = new PrintWriter(System.out);
    final int[] // final がついた
        a = {0, 2, 4},
        b = a; // アドレスをコピーしている

    out.println("# 操作前");
    out.println(a[0] + " " + a[1] + " " + a[2]);
    out.println(b[0] + " " + b[1] + " " + b[2]);

    /* 
     * final をつけても不変になるのはアドレス
     * データの操作は可能
     */
    for(int i=0; i<a.length; i++)
        b[i]++;

    out.println("# 操作後");
    out.println(a[0] + " " + a[1] + " " + a[2]);
    out.println(b[0] + " " + b[1] + " " + b[2]);

    out.flush();
}

実行結果

1
2
3
4
5
6
# 操作前
0 2 4
0 2 4
# 操作後
1 3 5
1 3 5

deep copy

コード

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
public static void main(String[] args) {
    PrintWriter out = new PrintWriter(System.out);
    int[]
        a = {0, 2, 4},
        b = a.clone(); // 配列の中身をコピーしている

    out.println("# 操作前");
    out.println(a[0] + " " + a[1] + " " + a[2]);
    out.println(b[0] + " " + b[1] + " " + b[2]);

    for(int i=0; i<a.length; i++)
        b[i]++;

    out.println("# 操作後");
    out.println(a[0] + " " + a[1] + " " + a[2]);
    out.println(b[0] + " " + b[1] + " " + b[2]);

    out.flush();
}

実行結果

1
2
3
4
5
6
# 操作前
0 2 4
0 2 4
# 操作後
0 2 4
1 3 5

shallow copy with function

コード

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static void main(String[] args) {
    PrintWriter out = new PrintWriter(System.out);
    int[]
        a = {0, 2, 4},
        b = copyfunc(a); // shallow copy を別メソッドで実行

    out.println("# 操作前");
    out.println(a[0] + " " + a[1] + " " + a[2]);
    out.println(b[0] + " " + b[1] + " " + b[2]);

    for(int i=0; i<a.length; i++)
        b[i]++;

    out.println("# 操作後");
    out.println(a[0] + " " + a[1] + " " + a[2]);
    out.println(b[0] + " " + b[1] + " " + b[2]);

    out.flush();
}
static int[] copyfunc(int[] array){
    return array;
}

実行結果

1
2
3
4
5
6
# 操作前
0 2 4
0 2 4
# 操作後
1 3 5
1 3 5

要素の操作を別メソッドで実行 1

コード

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
public static void main(String[] args) {
    PrintWriter out = new PrintWriter(System.out);
    int[] a = {0, 2, 4};

    out.println("# 操作前");
    out.println(a[0] + " " + a[1] + " " + a[2]);

    a = func(a);

    out.println("# 操作後");
    out.println(a[0] + " " + a[1] + " " + a[2]);

    out.flush();
}
static int[] func(int[] array){
    for(int i=0; i<array.length; i++)
        array[i]++;
    return array; 
}

実行結果

1
2
3
4
# 操作前
0 2 4
# 操作後
1 3 5

それはそう (小声)

要素の操作を別メソッドで実行 2

C/C++ でよく見る記法

コード

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
public static void main(String[] args) {
    PrintWriter out = new PrintWriter(System.out);
    int[] a = {0, 2, 4};

    out.println("# 操作前");
    out.println(a[0] + " " + a[1] + " " + a[2]);

    func(a);

    out.println("# 操作後");
    out.println(a[0] + " " + a[1] + " " + a[2]);

    out.flush();
}
static void func(int[] array){
    for(int i=0; i<array.length; i++)
        array[i]++;
}

実行結果

1
2
3
4
# 操作前
0 2 4
# 操作後
1 3 5

要素の操作を別メソッドで実行 3

C/C++ でよく見る記法 2

コード

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
public static void main(String[] args) {
    PrintWriter out = new PrintWriter(System.out);
    int[] a = {0, 2, 4};

    out.println("# 操作前");
    out.println(a[0] + " " + a[1] + " " + a[2]);

    func(a);

    out.println("# 操作後");
    out.println(a[0] + " " + a[1] + " " + a[2]);

    out.flush();
}
// final をつけても shallow copy と同じく, 要素は可変
static void func(final int[] array){
    for(int i=0; i<array.length; i++)
        array[i]++;
}

実行結果

1
2
3
4
# 操作前
0 2 4
# 操作後
1 3 5

引数を複数種用意してみる

コード

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public static void main(String[] args) {
    func(1);
    func(1, 2);
}

static void func(int a) {
    System.out.println("引数は 1 つ");
}

static void func(int a, int b) {
    System.out.println("引数は 2 つ");
}

実行結果

1
2
引数は 1 つ
引数は 2 つ

あとがき

調べたり考えたりすれば当たり前なんだけど, よく忘れるのでメモとして.

[ARTICLE: CC BY 4.0] [CODE BLOCK: CC0]
Built with Hugo
テーマ StackJimmy によって設計されています。