簡単な答え
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
メンバーを使用している場合にのみ、それを行う必要があります。ArrayList
List
あなたがおそらくしていないこと。
通常は、使用する最も一般的なインターフェイス ( 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
。