JavaRush /Java Blog /Random-JA /二重中括弧の初期化
Joysi
レベル 41

二重中括弧の初期化

Random-JA グループに公開済み

1. 二重中括弧の初期化

二重中括弧を使用した初期化 (以下、二重中括弧初期化と呼びます) は、リスト、セット、マップなどのコレクションを宣言と同時に作成する Java ツールです。
二重中括弧の初期化 - 1
サポートされている製品や通貨のリストなど、固定要素を含むリストが必要な場合、初期化と同時にリストを宣言すると、コードの可読性が向上します。これが、コード内で同時に初期化を行うコレクションを作成するための標準的な方法が他にないため、二重中括弧の初期化が人気を集めている理由です。残念ながら、他のプログラミング言語とは異なり、Java はリテラルのコレクションをサポートしていません。この制限により、たとえ少数の要素を含むadd()unmodifiableList を作成すると、最終的なラッピングで目的の要素を追加するために、繰り返し呼び出しの形式で多くのコード行を記述する必要があります。
List<Integer> list = new ArrayList<>();
list.add(2);
list.add(3);
list.add(5);
list.add(7);
List<Integer> unmodifiableList = Collections.unmodifiableList(list);
これは不必要に冗長な説明であるため、簡略化できます。私たちにとって便利な方法で静的リストを埋めてみましょう。つまり、初期化中に静的ブロックに直接埋めてみましょう。これはDouble brace初期化が役立ち、すべてを 1 行で書くことができます。
List<Integer> list = Collections.unmodifiableList(new ArrayList<Integer>() {{
        add(2);
        add(3);
        add(5);
}});
同様に、Double brace初期化は値と次の値を入力するのに役立ちますHashMap
Map<Integer, String> intToString = new HashMap<Integer, String>(){{
         put(1, "one");
         put(2, "two");
         put(3, "three");
 }};
すべて非常にエレガントに見えますが、二重中括弧の初期化をアンチパターンにする欠点があります。次の章でさらに詳しく見ていきます。

二重中括弧の初期化の長所と短所。

Double中括弧の初期化では、匿名の内部クラスの作成が使用されます。ただし、最初は表面上には隠されていますが、Double brace初期化によってクラスが作成され、使用するたびにそのインスタンスがさらに初期化されます。さらに、このプライベート クラスへの非表示の参照が使用されるため、メモリ リークが発生する可能性があります。また、匿名クラスの内部にアクセスできないため、ジェネリックスにゴースト演算子 (ダイヤモンド演算子 < >) を使用することもできません。
(翻訳者より: もう一度詳しく説明します。
最初の の後{、内部匿名クラスが作成され、2 番目の後に、{クラスのインスタンスを作成するときに初期化が行われ、その中で外部のフィールドとメソッドにアクセスできます (匿名) クラスに相対します。)
長所:
  1. コードの行数を減らす
  2. 1 つの式での作成と初期化。
マイナス点:
  1. あなたから隠された匿名クラスを作成します。
  2. そのため、インスタンスを使用するたびに追加コストがかかります。
  3. 毎回、それへの隠し参照が作成され、メモリ リークが発生する可能性があります。
評決:上記の短所と二重中括弧の代替手段の存在により、Java の世界では初期化はアンチパターンとみなされます。 子猫を救ってください

Java における二重中括弧の初期化の代替手段

良いニュースとしては、Java で同じ目標を達成する別の方法があるということです。以下に示すように、Collection クラスの Copy コンストラクターを使用して、ArrayList の作成と初期化を 1 行のコードで実装できます。
List<Integer> list = Collections.unmodifiableList(new ArrayList<>(Arrays.asList(2, 3, 5)));
Arrays.asList()ArrayListコピー コンストラクターに渡された固定長のリストを返します。Arrays.asList()とから返される固定長リストの違いに注意してくださいCollections.unmodifiableList()。 - の要素を追加または削除することはできませんArrayListが、 を使用してインデックスによって要素を変更できますset()。これは、 によって返されるリストでは実行できませんCollections.unmodifiableList()。小さなリストを取得したい場合は、これが最良の方法ですが、他のコレクションに対して透明性が低くなるため、-a を作成する前にSetリストを作成する必要があります。ただし、この場合、追加の内部匿名クラスが使用されるたびに作成されないため、二重中括弧の初期化よりも優れています。Java 8 を実行している場合は、別の代替方法があります。JDK 8 Stream API は、出力メソッドをコレクションに結合することにより、小さなコレクションを作成するのに役立ちます。 ListSetStream FactoryList
List<String> list = Collections.unmodifiableList(Stream.of("abc", "bcd", "cde").collect(toList()));
代わりに次のようにメソッドをSet使用できます。 Collectors.toSet()Collectors.toList()
Set<String> set = Collections.unmodifiableSet(Stream.of("abc", "bcd", "cde").collect(toSet()));
ちなみに、Stream collectメソッドは、生成するコレクションが変更から保護されることを保証しません。Java 8 では、返されるコレクション ( - ArrayListHashSet、 などHashMap) は非常に一般的です (変更可能) が、この事実は将来の JDK リリースで修正される可能性があります。Java での初期化についてはここまでですDouble brace。このテンプレートはテストやデモには使用できますが、運用環境での使用には十分ではありません。二重中括弧の初期化には固有の欠点があるため、特に利用可能な代替手段を考慮すると、最近ではアンチパターンになっています。私自身、静的マップを初期化するために今でもこの構造を使用しています。それだけです。List私はコンストラクターでのCollections作成と組み合わせて作成することを好むためです。Array.asListJava 8 を使用する場合は、Stream API を使用した設計とcollect(). 関連記事:このチュートリアルを気に入っていただき、Java プログラミング パターン、原則、ベスト プラクティスについてさらに詳しく知りたい場合は、当サイトの他の記事も参照してください。 推奨書籍:パターンとベスト プラクティスについて詳しく知りたい場合は、Joshua Bloch 著の 『Effective Programming』を読む必要があります。これに代わる本はありません。また、すでに Java に習熟していて、ユーモアのある表現スタイルが面白くて読みやすい、デザイン パターンに関する本を探している場合は、「Head First」に注目してください。デザインパターン"
翻訳者より: ブロッホの原著のロシア語への翻訳は失敗しているため、意図的にその本へのリンクを提供しました (たとえば、ビルダー = コンストラクター)。
記事の翻訳Java における Double Brace Initialization とは何ですか? アンチパターンの例(2015 年 10 月に公開)。
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION