簡単な答え
Java 9 以降:
List<String> strings = List.of("foo", "bar", "baz");
これにより、不変 Listの が得られるため、変更できません。
これは、事前設定しているほとんどの場合に必要なものです。
Java 8 以前:
List<String> strings = Arrays.asList("foo", "bar", "baz");
これにより、配列に裏打ちされたList*が得られるため、長さを変更できません。
ただし、 を呼び出すことができるList.set(...)ので、まだ変更可能です。
*
実装の詳細: これは、名前が付けられた 内のネストされたプライベート クラスjava.util.Arraysであり、単純な名前は同じですが、 とArrayListは
異なるクラスです。java.util.ArrayList
静的インポート
Arrays.asList静的インポートを使用すると、Java 8をさらに短くすることができます。
import static java.util.Arrays.asList;
...
List<String> strings = asList("foo", "bar", "baz");
最新の IDE *は、これを提案して実行します。
紛らわしいので、List.ofメソッドを単に として静的にインポートすることはお勧めしません。of
*
たとえば、IntelliJ IDEA では、押しAlt+Enterて選択しますStatic import method...
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または、 aからa に移動できますList。
import static java.util.stream.Collectors.toList;
...
var strings = Stream.of("foo", "bar", "baz").toList(); // Java 16
List<String> strings = Stream.of("foo", "bar", "baz").collect(toList()); // Java 8
ただし、できれば、Streamに収集せずに を使用するだけListです。
特に*が必要な場合java.util.ArrayList
を事前入力して後で追加する場合は、ArrayList
List<String> strings = new ArrayList<>(List.of("foo", "bar"));
strings.add("baz");
または Java 8 以前の場合:
List<String> strings = new ArrayList<>(asList("foo", "bar"));
strings.add("baz");
または使用Stream:
import static java.util.stream.Collectors.toCollection;
List<String> strings = Stream.of("foo", "bar")
.collect(toCollection(ArrayList::new));
strings.add("baz");
ただし、Streamに収集するのではなく、 を直接使用することをお勧めしListます。
*おそらく特に . は必要ありませんArrayList。JEP 269を引用するには:
事前定義された一連の値を使用して可変コレクション インスタンスを初期化するためのいくつかのユース ケースがあります。通常は、これらの定義済みの値を不変コレクションに入れ、コピー コンストラクターを介して可変コレクションを初期化することをお勧めします。
(私のものを強調)
実装ではなくインターフェースへのプログラム
コード内でリストを として宣言したと言いましたが、にない のArrayListメンバーを使用している場合にのみ、それを行う必要があります。ArrayListList
あなたがおそらくしていないこと。
通常は、使用する最も一般的なインターフェイス ( Iterable、Collection、または など) で変数を宣言Listし、特定の実装 ( ArrayList、LinkedListまたは などArrays.asList()) で変数を初期化する必要があります。
そうしないと、コードをその特定のタイプに制限することになり、変更したいときに変更するのが難しくなります。
たとえば、 anArrayListを a に渡す場合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 random access, .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
}
InputStreamもう 1 つの例は、通常は aFileInputStreamまたは aである変数を常に宣言することです。これは、いつのBufferedInputStream日か、あなたまたは他の誰かが他の種類の を使用したくなるからですInputStream。