一行代码初始化ArrayList

一行代码初始化ArrayList

技术背景

在Java编程中,经常需要初始化ArrayList。传统的初始化方式可能需要多行代码,不够简洁。因此,寻找一种简洁的一行代码初始化ArrayList的方法是很有必要的。

实现步骤

Java 9及以后版本

  • 创建不可变列表
1
2
3
4
5
6
7
import java.util.List;

public class Main {
public static void main(String[] args) {
List<String> strings = List.of("foo", "bar", "baz");
}
}

List.of(...) 方法会返回一个不可变的 List,不允许改变其内容,且不允许包含 null 元素。

  • 创建可变的 ArrayList
1
2
3
4
5
6
7
8
import java.util.ArrayList;
import java.util.List;

public class Main {
public static void main(String[] args) {
List<String> strings = new ArrayList<>(List.of("foo", "bar"));
}
}

Java 8及更早版本

  • 使用 Arrays.asList 方法
1
2
3
4
5
6
7
8
import java.util.Arrays;
import java.util.List;

public class Main {
public static void main(String[] args) {
List<String> strings = Arrays.asList("foo", "bar", "baz");
}
}

Arrays.asList(...) 方法返回一个由数组支持的 List,其长度不能改变,但可以调用 List.set(...) 方法修改元素,允许包含 null 元素。

  • 使用静态导入简化代码
1
2
3
4
5
6
7
8
import static java.util.Arrays.asList;
import java.util.List;

public class Main {
public static void main(String[] args) {
List<String> strings = asList("foo", "bar", "baz");
}
}

使用 Stream

  • 创建 Stream
1
2
3
4
5
6
7
import java.util.stream.Stream;

public class Main {
public static void main(String[] args) {
Stream<String> strings = Stream.of("foo", "bar", "baz");
}
}
  • Stream 转换为 List
1
2
3
4
5
6
7
8
9
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Main {
public static void main(String[] args) {
List<String> strings = Stream.of("foo", "bar", "baz").collect(Collectors.toList());
}
}

使用第三方库

  • Guava
1
2
3
4
5
6
7
8
9
import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.List;

public class Main {
public static void main(String[] args) {
ArrayList<String> places = Lists.newArrayList("Buenos Aires", "Córdoba", "La Plata");
}
}
  • Eclipse Collections
1
2
3
4
5
6
7
8
import org.eclipse.collections.api.list.MutableList;
import org.eclipse.collections.impl.factory.Lists;

public class Main {
public static void main(String[] args) {
MutableList<String> list = Lists.mutable.with("Buenos Aires", "Córdoba", "La Plata");
}
}

其他方法

  • 双大括号初始化
1
2
3
4
5
6
7
8
9
10
11
12
import java.util.ArrayList;
import java.util.List;

public class Main {
public static void main(String[] args) {
List<String> list = new ArrayList<String>() {{
add("A");
add("B");
add("C");
}};
}
}

这种方法会创建一个 ArrayList 的匿名子类,不建议使用,因为会带来额外的开销。

核心代码

Java 9及以后版本创建可变 ArrayList

1
2
3
4
5
6
7
8
import java.util.ArrayList;
import java.util.List;

public class Main {
public static void main(String[] args) {
List<String> strings = new ArrayList<>(List.of("foo", "bar"));
}
}

Java 8及更早版本使用 Arrays.asList

1
2
3
4
5
6
7
8
import java.util.Arrays;
import java.util.List;

public class Main {
public static void main(String[] args) {
List<String> strings = Arrays.asList("foo", "bar", "baz");
}
}

使用 Stream 转换为 List

1
2
3
4
5
6
7
8
9
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Main {
public static void main(String[] args) {
List<String> strings = Stream.of("foo", "bar", "baz").collect(Collectors.toList());
}
}

最佳实践

  • 如果需要一个不可变的列表,优先使用 Java 9 及以后的 List.of 方法。
  • 如果需要一个可变的列表,且在 Java 9 及以后版本,可使用 new ArrayList<>(List.of(...))
  • 在 Java 8 及更早版本,可使用 Arrays.asList 方法,但要注意其返回的列表长度不可变。
  • 尽量避免使用双大括号初始化,因为会创建匿名子类,增加开销。

常见问题

  • Arrays.asList 方法的问题Arrays.asList 返回的列表长度不可变,且处理继承时可能会有问题。例如:
1
2
3
4
5
6
7
8
9
10
11
class A {}
class B extends A {}

import java.util.Arrays;
import java.util.List;

public class Main {
public static List<A> getAList() {
return Arrays.asList(new B()); // 编译错误
}
}

解决方法是使用 new ArrayList<A>(Arrays.<A>asList(b1, b2, b3))

  • List.of 方法不允许 null 元素:如果尝试在 List.of 中使用 null 元素,会抛出 NullPointerException 异常。