読者です 読者をやめる 読者になる 読者になる

Java の java.util.Arrays.asList について少し調べてみた

Java .NET

調べる機会があったので…Oracle Technology Network for Java Developers | Oracle Technology Network | Oracle

asList メソッドから引用

指定された配列に連動する固定サイズのリストを返します。

ここだけ読んで、.NET でいう Enumerable.ToList<TSource> メソッド か、List<T> コンストラクタ (IEnumerable<(T>) と同じだと思ったんだけど、続きがあって

asList メソッドから引用

返されたリストへの変更は、そのまま配列に書き込まれます。

て記述があった。これだと動きが異なるな〜と思って比べてみた。

Java (Groovy で実装してます)

class CustomInt {
  int value;
  public CustomInt(int val) {
    value = val
  }
  public void increment() {
    value++
  }
  public String toString() {
    return value
  }
}

CustomInt[] c = [ new CustomInt(1), new CustomInt(2),  new CustomInt(3) ]
def l = Arrays.asList(c)
l[1] = new CustomInt(4)
l[2].increment()
l[2].increment()

l.each { println it } // 1 4 5
c.each { println it } // 1 4 5 上と同じ!

.NET (C#)

using System;
using System.Collections.Generic;

class CustomInt
{
  public int Value { get; set; }
  public CustomInt(int val)
  {
    Value = val;
  }
  public void Increment()
  {
    Value++;
  }
  public override string ToString()
  {
    return Value.ToString();
  }
}

class Program
{
  static void Main(string[] args)
  {
    var c = new CustomInt[] { new CustomInt(1), new CustomInt(2), new CustomInt(3) };
    var l = new List<CustomInt>(c);
    l[1] = new CustomInt(4);
    l[2].Increment();
    l[2].Increment();

    l.ForEach(Console.WriteLine); // 1 4 5
    foreach (var item in c)
    {
      Console.WriteLine(item); // 1 2 5 上と違う!!!
    }
  }
}

Java の方は、List も配列も出力結果は同じになったけど、.NET は違う。リストに対する操作が配列にも反映されるのは Java だけ。
ただ、.NET も要素については浅いコピー (shallow copy) なので、要素に対して行った操作は、.NET Java 共に配列にも反映される。(見てるインスタンスが同じだから)
Java の asList は List に対して、要素の追加・削除が出来なかった。(例外が発生した)
 やっぱり、メソッド名からして 「as」List だし、配列を List に見立てただけなのかな。「to」List だと、配列から List を作りました!ってイメージだけど。