简单的答案
在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
s
为什么必须是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());
但最好使用Stream
而不将其收集到中List
。
如果您确实需要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");
但是同样,最好Stream
直接使用Direct而不是将其收集到List
。
程序接口,而不是实现
您说过已ArrayList
在代码中将列表声明为,但仅当使用ArrayList
的不是in的某个成员时才应这样做List
。
您最有可能不这样做。
通常你应该只通过通用接口,你要使用(例如声明变量Iterable
,Collection
或List
),并与具体的实施对它们进行初始化(例如ArrayList
,LinkedList
或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
}
另一个示例将始终将变量声明InputStream
为FileInputStream
a BufferedInputStream
,即使它通常是a 或a ,因为有一天您或其他人将想要使用其他类型的InputStream
。
ArrasyList<String> places = ["Buenos Aires", "Córdoba", "La Plata"]