简单的答案
在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已经足够短,而且阅读效果很好。
使用Streams
为什么必须是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为FileInputStreama BufferedInputStream,即使它通常是a 或a ,因为有一天您或其他人将想要使用其他类型的InputStream。
ArrasyList<String> places = ["Buenos Aires", "Córdoba", "La Plata"]