1行でのJavaリストの初期化

1.はじめに

このクイックチュートリアルでは、ワンライナーを使用してリストを初期化する方法を調査します。

2.配列から作成

配列からリストを作成できます。配列リテラルのおかげで、1行で初期化できます。

List list = Arrays.asList(new String[]{"foo", "bar"});

配列の作成を処理するためにvarargsメカニズムを信頼できます。これにより、より簡潔で読みやすいコードを記述できます。

@Test public void givenArraysAsList_thenInitialiseList() { List list = Arrays.asList("foo", "bar"); assertTrue(list.contains("foo")); }

このコードの結果インスタンスはListインターフェースを実装しますが、java.util.ArrayListでもLinkedListでもありません。代わりに、元の配列に裏打ちされたリストであり、2つの意味があります。

ただし、クラスの名前はたまたまArrayListですが、java.util.Arraysパッケージに含まれています。

2.1。固定サイズ

Arrays.asListの結果インスタンスのサイズは固定されています。

@Test(expected = UnsupportedOperationException.class) public void givenArraysAsList_whenAdd_thenUnsupportedException() { List list = Arrays.asList("foo", "bar"); list.add("baz"); }

2.2。共有リファレンス

元の配列とリストは、オブジェクトへの同じ参照を共有します。

@Test public void givenArraysAsList_whenCreated_thenShareReference(){ String[] array = {"foo", "bar"}; List list = Arrays.asList(array); array[0] = "baz"; assertEquals("baz", list.get(0)); }

3.ストリームから作成(Java 8)

ストリームをあらゆる種類のコレクションに簡単に変換できます

したがって、Streamsのファクトリメソッドを使用すると、リストを1行で作成および初期化できます。

@Test public void givenStream_thenInitializeList(){ List list = Stream.of("foo", "bar") .collect(Collectors.toList()); assertTrue(list.contains("foo")); }

ここで、Collectors.toList()が返されたリストの正確な実装を保証しないことをマークする必要があります。

返されたインスタンスの可変性、直列化可能性、またはスレッドセーフに関する一般的な契約はありません。したがって、コードはこれらのプロパティのいずれにも依存しないでください。

一部のソースは、Stream.of(…).collect(…)のメモリとパフォーマンスのフットプリントがArrays.asList()よりも大きい可能性があることを強調していますが、ほとんどの場合、それは非常に微調整されているため、ほとんど違いはありません。

4.ファクトリメソッド(Java 9)

JDK 9では、コレクションにいくつかの便利なファクトリメソッドが導入されました。

List list = List.of("foo", "bar", "baz"); Set set = Set.of("foo", "bar", "baz");

重要な詳細の1つは、返されるインスタンスが不変であることです。それ以外に、ファクトリメソッドにはスペース効率とスレッドセーフにいくつかの利点があります。

このトピックについては、この記事で詳しく説明します。

5.中括弧の初期化

いくつかの場所で、次のような「二重中括弧の初期化」と呼ばれるメソッドを見つけることができます。

@Test public void givenAnonymousInnerClass_thenInitialiseList() { List cities = new ArrayList() {{ add("New York"); add("Rio"); add("Tokyo"); }}; assertTrue(cities.contains("New York")); }

「二重中括弧の初期化」という名前は、かなり誤解を招く恐れがあります。構文はコンパクトでエレガントに見えるかもしれませんが、内部で起こっていることを危険なほど隠しています。

Javaには実際には「二重中括弧」構文要素はありません。これらは意図的にこのようにフォーマットされた2つのブロックです。

外側の中括弧を使用して、ArrayListのサブクラスとなる匿名の内部クラスを宣言します。これらの中括弧内で、サブクラスの詳細を宣言できます。

いつものように、インスタンス初期化ブロックを使用できます。これは、中括弧の内側のペアの由来です。

この構文の簡潔さは魅力的ですが、アンチパターンと見なされます。

二重中括弧の初期化の詳細については、こちらの記事をご覧ください。

6.結論

最新のJavaには、コレクションを1行で作成するためのいくつかのオプションがあります。私たちが選んだ方法は、技術的な理由ではなく、ほぼ完全に個人的な好みによるものです。

重要なポイントは、見た目は優雅ですが、匿名の内部クラス初期化のアンチパターン(別名「二重中括弧」)には多くの悪影響があるということです。

いつものように、コードはGitHubで入手できます。