一行でArrayListの初期化

java collections arraylist initialization


テスト用にオプションの一覧表を作ろうと思いました。最初は、このようにしました。

ArrayList<String> places = new ArrayList<String>();
places.add("Buenos Aires");
places.add("Córdoba");
places.add("La Plata");

その後、以下のようにリファクタリングしました。

ArrayList<String> places = new ArrayList<String>(
    Arrays.asList("Buenos Aires", "Córdoba", "La Plata"));

もっと良い方法はないのでしょうか?




Answer 1 coobird


実際、 ArrayList を初期化する「最善の」方法は、新しい List を作成する必要がないため、作成したメソッドです。

ArrayList<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");

問題は、その list インスタンスを参照するために必要な入力がかなり必要なことです。

インスタンスの初期化(「ダブルブレースの初期化」とも呼ばれています)で匿名のインナークラスを作るなどの代替案もあります。

ArrayList<String> list = new ArrayList<String>() {{
    add("A");
    add("B");
    add("C");
}};

ただし、最終的にインスタンス初期化子を持つ ArrayList のサブクラスであり、そのクラスは1つのオブジェクトを作成するためだけに作成されるため、私はそのメソッドがあまり好きではありません。 。

場合はどうだったでしょう素敵でしたコレクションリテラルの提案のためのプロジェクトコインが受け入れられました(。それはJava 7で導入される予定が、それは、Java 8のいずれかの一部となる可能性はありませんして):

List<String> list = ["A", "B", "C"];

残念ながら、 ArrayList ではなく不変の List を初期化するため、ここでは役に立ちません。さらに、まだ使用できない場合でも、まだ使用できません。




Answer 2 Tom


List として宣言するだけの場合はもっと簡単です。ArrayListである必要がありますか?

List<String> places = Arrays.asList("Buenos Aires", "Córdoba", "La Plata");

または、要素が1つしかない場合。

List<String> places = Collections.singletonList("Buenos Aires");

これは、 places不変であることを意味します(変更しようとすると、 UnsupportedOperationException 例外がスローされます)。

具体的な ArrayList である可変リストを作成するには、不変リストから ArrayList を作成できます。

ArrayList<String> places = new ArrayList<>(Arrays.asList("Buenos Aires", "Córdoba", "La Plata"));



Answer 3 Christoffer Hammarström


単純な答え

Java 9以降、後 List.of() を添加しました。

List<String> strings = List.of("foo", "bar", "baz");

Javaの10以降、これをして短縮することが可能と var キーワード。

var strings = List.of("foo", "bar", "baz");

これにより、不変の List が提供されるため、変更できません。
どっちがいいかというとプレポしてる場合がほとんどだな


Java 8 またはそれ以前のバージョン。

List<String> strings = Arrays.asList("foo", "bar", "baz");

これにより、配列に基づく List が提供されるため、長さを変更できません。
ただし、 List.set を呼び出すことができるため、変更可能です。


静的インポートを使用すると、 Arrays.asList をさらに短くすることができます。

List<String> strings = asList("foo", "bar", "baz");

スタティックインポートです。

import static java.util.Arrays.asList;  

最新の IDE が自動的にあなたのために提案してくれるでしょう。
たとえば、IntelliJ IDEAでは、 Alt+Enter を押して、 Static import method... を選択します。


ただし、混乱を招くため、 List.of メソッドを of に短縮することはお勧めしません。
List.of はすでに十分に短く、読みやすくなっています。


Stream の使用

なぜ List でなければならないのですか?
Java 8以降では、より柔軟な Stream を使用できます。

Stream<String> strings = Stream.of("foo", "bar", "baz");

Stream を連結できます:

Stream<String> strings = Stream.concat(Stream.of("foo", "bar"),
                                       Stream.of("baz", "qux"));

または、 Stream から List 移動することもできます。

import static java.util.stream.Collectors.toList;

List<String> strings = Stream.of("foo", "bar", "baz").collect(toList());

しかし、できれば、 StreamList 収集せずに使用するだけです。


特に java.util.ArrayList本当に必要な場合

(おそらくそうではありません。)
JEP 269(私の強調)を引用するには:

ある小さなセット定義済みの値のセットで変更可能なコレクションのインスタンスを初期化するための使用例は。通常、これらの事前定義された値を不変のコレクションに入れ、次にコピーコンストラクターを介して可変コレクションを初期化することをお勧めします。


あなたがしたい場合は、両方の事前移入 ArrayList 、(なぜ?)、その後、それに使用を追加

ArrayList<String> strings = new ArrayList<>(List.of("foo", "bar"));
strings.add("baz");

または Java 8 またはそれ以前のバージョンで使用する必要があります。

ArrayList<String> strings = new ArrayList<>(asList("foo", "bar"));
strings.add("baz");

または Stream を使用して:

import static java.util.stream.Collectors.toCollection;

ArrayList<String> strings = Stream.of("foo", "bar")
                             .collect(toCollection(ArrayList::new));
strings.add("baz");

ただし、繰り返しますが、 List 収集するのではなく、直接 Stream を使用することをお勧めします。


実装ではなくインターフェースへのプログラム

あなたは、あなたのようにリストを宣言したと述べた ArrayList のコード内に、しかし、あなたはあなたがいくつかのメンバー使用している場合があることを行う必要がある ArrayList にない List

あなたがやっていない可能性が高い

通常は、使用する最も一般的なインターフェイス(例: IterableCollection 、または List )で変数を宣言し、特定の実装(例: ArrayListLinkedList または Arrays.asList() )で初期化する必要があります。

そうでなければ、その特定の型にコードを制限していることになり、変更したいときに変更するのが難しくなります。

たとえば、あなたが渡している場合 ArrayList する void method(...)

// Iterable if you just need iteration, for (String s : strings):
void method(Iterable<String> strings) { 
    for (String s : strings) { ... } 
}

// Collection if you also need .size(), .isEmpty(), or .stream():
void method(Collection<String> strings) {
    if (!strings.isEmpty()) { strings.stream()... }
}

// List if you also need .get(index):
void method(List<String> strings) {
    strings.get(...)
}

// Don't declare a specific list implementation
// unless you're sure you need it:
void method(ArrayList<String> strings) {
    ??? // You don't want to limit yourself to just ArrayList
}

別の例としては、通常 FileInputStream または BufferedInputStream であっても、常に InputStream 変数を宣言します。ある日、あなたや他の誰かが他の種類の InputStream を使用したくなるからです。




Answer 4 Randyaa


1号サイズの簡単なリストが必要な場合。

List<String> strings = new ArrayList<String>(Collections.singletonList("A"));

複数のオブジェクトのリストが必要な場合

List<String> strings = new ArrayList<String>();
Collections.addAll(strings,"A","B","C","D");



Answer 5 Paweł Adamski


グアバあなたは書くことができます。

ArrayList<String> places = Lists.newArrayList("Buenos Aires", "Córdoba", "La Plata");

Guavaには他にも便利な静的コンストラクタがあります。あなたはそれらについてここで読むことができます。