一行初始化ArrayList?

我想创建用于测试目的的选项列表。首先,我这样做:

ArrayList places = new ArrayList();

places.add(“Buenos Aires”);

places.add(“Córdoba”);

places.add(“La Plata”);

然后,我将代码重构如下:

ArrayList places = new ArrayList( Arrays.asList(“Buenos Aires”, “Córdoba”, “La Plata”));

有一个更好的方法吗?

高分回答:

很多的知识点,真的需要写出来才会掌握!!! \color{purple}很多的知识点,真的需要写出来才会掌握!!!{~}很多的知识点,真的需要写出来才会掌握!!! 

简单的答案 Java 10或更高版本:

var strings = List.of("foo", "bar", "baz");

复制代码

这将为您提供一成不变的 List,因此无法更改。 在大多数情况下,这是您想要的。

Java 9

如果您使用的是Java 9,则不能使用var关键字:


List<String> strings = List.of("foo", "bar", "baz");

复制代码

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方法静态导入为just of,因为这很令人困惑。

*例如,在IntelliJ IDEA中,按Alt+Enter并选择Static import method… 使用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;
...
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直接使用Direct而不是将其收集到中List。

*您可能不需要特别的ArrayList。引用JEP 269:

有少量用例用于使用预定义的值集初始化可变集合实例。通常最好将这些预定义值放在不可变的集合中,然后通过复制构造函数初始化可变集合。
复制代码

(强调我的) 程序接口,而不是实现

您说过已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。

原创文章,作者:睿达君,如若转载,请注明出处:http://zrrd.net.cn/902.html

发表评论

登录后才能评论
咨询电话
联系电话:0451-81320577

地址:哈尔滨市松北区中小企业总部基地13F

微信咨询
微信咨询
QQ咨询
分享本页
返回顶部