一行代码初始化 Java 中的 ArrayList:从新手到专家
想象一下:你在编写测试、创建原型,或者只是想快速定义一个字符串列表。在 Python 中,这看起来像 my_list = ["a", "b", "c"]。而在 Java 中……麻烦就来了。难道每次都需要写三四行代码,为每个元素调用 add() 方法吗?剧透:不需要。在本文中,我们将详细讲解所有用一行代码初始化 ArrayList 的方法,回答 Stack Overflow 上最常见的问题,并展示如何根据任务选择合适的方法。开始吧!
本文基于 Stack Overflow 上一个真实的热门问题,该问题已获得数千次浏览。我们对其进行了教学化改编,以便您不仅能复制代码,还能理解它为什么能(或不能)工作。
为什么简单的初始化会让人头疼?
Java 中有 ArrayList——一个动态数组。但它不像数组那样有内置的带数据初始化的字面量(例如 String[] arr = {"a", "b", "c"};)。因此,新手常常这样写:
ArrayList<String> list = new ArrayList<>();list.add("Java");list.add("Python");list.add("JavaScript");这虽然可行,但占了 4 行代码。如果元素有 10 个呢?100 个呢?我们希望代码更紧凑。让我们来探讨所有合法(以及不太合法)的、用一行代码实现这一目标的方法。
方法 1:经典方法——Arrays.asList()
这是您在 Stack Overflow 答案中找到的最流行的方法:
ArrayList<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));这里,我们首先使用 Arrays.asList() 创建一个固定大小的列表,然后将其传递给 ArrayList 的构造函数。结果是一个完全可变的列表。您可以添加、删除和修改元素。
重要提示: Arrays.asList() 本身并不返回 ArrayList!它返回的是其内部实现的一个固定大小的列表。如果您尝试对 Arrays.asList() 的结果调用 add(),将会得到 UnsupportedOperationException。请记住这一点——这是面试和 Stack Overflow 帖子中最常见的问题。
何时使用?
- 当您需要一个可变列表时。
- 当您使用 Java 7 或更低版本时(Java 9 之前)。
方法 2:Java 9+——List.of()
从 Java 9 开始,出现了工厂方法 List.of():
List<String> immutableList = List.of("a", "b", "c");简短、美观、简洁。但有一个问题:得到的列表是不可变的。您无法添加或删除元素。如果尝试这样做,将会得到 UnsupportedOperationException。
如果您确实需要 ArrayList,请将其包装起来:
ArrayList<String> list = new ArrayList<>(List.of("a", "b", "c"));如果您使用 Java 9 或更高版本,此方法优于 Arrays.asList(),因为 List.of() 返回一个结构上不可变的列表(无法更改大小),而 Arrays.asList() 允许通过 set() 修改元素。
何时使用?
- Java 9+
- 需要简洁的语法
- 您不打算修改列表(或者将其包装到
ArrayList中)
方法 3:双大括号初始化——反模式
在 Stack Overflow 上,这个技巧经常出现。它看起来像这样:
ArrayList<String> list = new ArrayList<>() {{ add("a"); add("b"); add("c");}};这里发生了什么?我们创建了一个继承自 ArrayLi 的匿名内部类。