简单的答案
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
,尽管它们的简单名称相同。
静态导入
您可以使用静态导入使 Java 8Arrays.asList
更短:
import static java.util.Arrays.asList;
...
List<String> strings = asList("foo", "bar", "baz");
任何现代 IDE *都会建议并为您执行此操作。
我不建议将List.of
方法静态导入 just of
,因为它很混乱。
*
例如,在 IntelliJ IDEA 中,您按下Alt+Enter
并选择Static import method...
使用Stream
_
为什么它必须是一个List
?
使用 Java 8 或更高版本,您可以使用Stream
更灵活的 a:
Stream<String> strings = Stream.of("foo", "bar", "baz");
您可以连接Stream
s:
Stream<String> strings = Stream.concat(Stream.of("foo", "bar"),
Stream.of("baz", "qux"));
或者您可以从 aStream
转到 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:
有一小部分用例用于使用一组预定义的值初始化可变集合实例。通常最好将这些预定义值放在不可变集合中,然后通过复制构造函数初始化可变集合。
(强调我的)
编程接口,而不是实现
您说您已在代码中将列表声明为 an ArrayList
,但仅当您使用的某些成员ArrayList
不在List
.
您很可能不会这样做。
通常,您应该只通过您将要使用的最通用接口(例如Iterable
,Collection
或)声明变量,并使用特定实现(例如,或)List
初始化它们。ArrayList
LinkedList
Arrays.asList()
否则,您会将代码限制为该特定类型,并且在您想要更改时会更难。
例如,如果您将 an 传递ArrayList
给 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
}
另一个例子是总是声明变量 an,InputStream
即使它通常是 aFileInputStream
或 a BufferedInputStream
,因为有一天你或其他人会想要使用其他类型的InputStream
。