Collectionsのメソッドを適応できるListの作り方
タイトルの通り。
ざっくりとまとめると:
-
List.of()
が返すリストは、immutable。Arrays.asList()
が返すリストは、長さが変えられないリスト。そのため、Collections
のメソッドでも要素の追加・削除などに関わるものは使えない -
Collections
のメソッドを使えるリストを作成したい場合:
1. 新しく空のリストを作成後、add()
で各要素を追加
2. 新しく空のリストを作成後、Collections.addAll()
で引数に追加したい要素を入れる
だけど、その前になぜこの記事を書こうと思ったか、きっかけとなったコードを紹介してから詳細に入る。
Listなのに、Collectionsのメソッドが使えない場合があるらしい
List
たるもの、全てCollecitons
のメソッドが使えるに違いない[1]と思って書いた以下のようなコード。残念ながらexception
が投げられてしまう。
List<Integer> list = List.of(3, 3, 3, 4);
Collections.sort(list); // UnsupportedOperationException
さて、この原因は、List.of()
の返すリストが、immutable[2]なことによる。
他にもArrays.asList()
は長さの変えられないリストを返すので、このメソッドが返すリストに新たに要素を加えたり減らしたりはできない。
Integer[] array = {1,4,6,7};
List<Integer> arrayToList = Arrays.asList(array);
arrayToList.set(1, 10);
System.out.println(Arrays.toString(array));// [1,10,6,7]
System.out.println(arrayToList); // [1,10,6,7]
arrayToList.add(20); // throws UnsupportedOperationException
arrayToList.remove(2); // throws UnsupportedOperationException
Arrays.asList(int())とArrays.asList(Integer[])の違い
でも触れたように、ここで新しくつくられたリスト型のarrayToList
での変更は、元の配列array
にも反映される。新しいリストも、元の配列も、共にヒープ内の同じデータを参照(厳密にはpoint)してるだけなので。こういうのをan Array-backed listというらしい[3]。
Collectionsのメソッドが使えるListを作りたい時
さて、ようやく本題ですが、Collectionsメソッドが使えるListを作りたい場合、以下の2つの方法が挙げられる。
1. ArrayList.add()
新しく空のリストを作成し、そこにadd()
で要素を追加していく。for-loopで順番に要素を追加していくときなどに便利!
例
List<Integer> arraylist = new ArrayList<>();
arraylist.add(4);
arraylist.add(2);
System.out.println(arraylist); // [4,2]
int i = 1;
while(arraylist.size() < 10){
arraylist.add(++i);
}
System.out.println(arraylist);
2. Collections.addAll()
新しい空のリストを作成するのは、上記の方法と共通だが、その後に格納する要素をワンラインで格納できるのが、このメソッド。
public static <T> boolean addAll(Collection<? super T> c, T.. a)
このメソッドは、c.addAll(Arrays.asList(elements))
を行っている。ほかの方法で要素追加もできるが、大抵の場合はこのメソッドの方が早い(と、以下の公式ドキュメントがおっしゃっている)。
例
List<String> browserlist = new ArrayList<>();
Collections.addAll(browserlist, "Google", "Mozila FireFox", "Yahoo");
browserlist.add("Opera");
System.out.println(browserlist);
// [Google, Mozila FireFox, Yahoo, Opera]
test.java書き直し
List<Integer> list = new ArrayList<>();
Collections.addAll(list, 1,4,2,3,2,5);
Collections.sort(list); // [5, 4, 3, 2, 2, 1]
-
だって
List
はCollections
のインターフェースだから!Collections in Java: Hierarchy of Collection Framework ↩︎ -
不可変とでも言うのかな。
String
型もimmutableで値が変えられない。軽く調べても、浸透している共通語はなさそうだったので、便宜上英語のままにします。 ↩︎ -
a backed listということも('Chapter 5: Core Java APIs' from "OCP Oracle Certified Professional Java SE 11 Programmer I Study Guide: Exam 1Z0-815")。そして例によって、また対応する日本語分カラナイヨ。このあたりの用語がまとまった記事も、そのうち作りたい。 ↩︎
Discussion