0

0

如何在Java中使用Arrays.asList创建列表

P粉602998670

P粉602998670

发布时间:2025-09-19 11:58:01

|

770人浏览过

|

来源于php中文网

原创

Arrays.asList返回的列表是原数组的视图,非独立副本,不支持增删操作,修改会同步到原数组。

如何在java中使用arrays.aslist创建列表

在Java中,

Arrays.asList
方法提供了一种非常便捷的方式,可以将一个数组转换成
List
接口的实现。然而,这个方法返回的
List
并非我们日常熟悉的
java.util.ArrayList
,而是一个由
Arrays
类内部定义的固定大小的私有静态
ArrayList
类。这意味着你不能对这个列表进行添加或删除元素的操作,否则会抛出
UnsupportedOperationException
。它本质上是原数组的一个“视图”,对列表元素的修改会直接反映到原数组上,反之亦然。

解决方案

使用

Arrays.asList
将数组转换为列表,最直接的方式就是调用它,传入你的数组。这个方法接受一个可变参数(varargs),所以你可以传入一个数组,或者一系列的元素。

例如,如果你有一个字符串数组

String[] myArray = {"Apple", "Banana", "Cherry"};
List myList = Arrays.asList(myArray);

System.out.println("原始列表: " + myList); // 输出: [Apple, Banana, Cherry]

如果想直接传入元素:

立即学习Java免费学习笔记(深入)”;

List numbers = Arrays.asList(1, 2, 3, 4, 5);
System.out.println("数字列表: " + numbers); // 输出: [1, 2, 3, 4, 5]

需要强调的是,尽管

myList
现在看起来像一个列表,但它与原数组
myArray
共享底层数据。这意味着,如果你修改了列表中的某个元素,原数组中对应位置的元素也会随之改变。

myList.set(0, "Apricot"); // 修改列表的第一个元素
System.out.println("修改后列表: " + myList); // 输出: [Apricot, Banana, Cherry]
System.out.println("原数组: " + Arrays.toString(myArray)); // 输出: [Apricot, Banana, Cherry]

反过来也一样,修改原数组也会影响到列表。

myArray[1] = "Blueberry"; // 修改原数组的第二个元素
System.out.println("再次修改后列表: " + myList); // 输出: [Apricot, Blueberry, Cherry]

这在使用时是一个非常重要的特性,也是很多开发者容易踩坑的地方。它不是创建一个独立的列表副本,而是提供了一个基于数组的列表“视图”。

为什么我用
Arrays.asList
创建的列表不能添加或删除元素?

这几乎是我在刚接触Java时,或者在一些初级面试中,经常被问到或者自己犯错的一个点。

Arrays.asList
返回的
List
对象,确实是一个
java.util.List
的实现,但它并不是我们通常使用的
java.util.ArrayList
。它实际上是
java.util.Arrays
类内部的一个私有静态类
ArrayList
(注意,这个
ArrayList
java.util.ArrayList
不是同一个类!)。这个内部类继承自
AbstractList
,并且它的
add()
remove()
方法并没有被重写以支持修改操作,或者说,它们的实现直接就是抛出
UnsupportedOperationException

这个设计的初衷,在我看来,是为了提供一个轻量级的、固定大小的列表视图,方便对数组进行列表操作,比如迭代、查找等,而不是为了创建一个可变集合。当你尝试执行

add()
remove()
操作时,你会立即得到一个运行时错误:

List fruits = Arrays.asList("Apple", "Orange");
try {
    fruits.add("Grape"); // 尝试添加元素
} catch (UnsupportedOperationException e) {
    System.out.println("添加失败: " + e.getMessage()); // 输出: 添加失败: null
}

try {
    fruits.remove(0); // 尝试删除元素
} catch (UnsupportedOperationException e) {
    System.out.println("删除失败: " + e.getMessage()); // 输出: 删除失败: null
}

这种行为其实是符合其设计理念的:它只是数组的一个“瘦包装器”,既然底层是固定大小的数组,那么对其进行大小改变的操作自然就不被允许了。理解这一点,能帮助我们避免很多不必要的运行时错误,并选择正确的工具来处理数据集合。

Arrays.asList
返回的列表与原数组是独立的吗?

绝对不是独立的,这是一个非常关键的误解点。我个人在项目中就遇到过因为不清楚这一点而导致的数据不一致问题。

Arrays.asList
方法返回的
List
,本质上是原数组的一个“门面”或者说“视图”。它没有创建新的数据结构来存储元素,而是直接引用了你传入的那个数组。

这意味着,列表和数组共享同一块内存区域。对列表元素的修改,会直接反映到原数组上;反之,对原数组元素的修改,也会立刻体现在列表中。这种“同生共死”的关系,既是它的一个特性,也是一个潜在的陷阱。

让我们通过一个具体的例子来看看:

情感家园企业站5.0 多语言多风格版
情感家园企业站5.0 多语言多风格版

一套面向小企业用户的企业网站程序!功能简单,操作简单。实现了小企业网站的很多实用的功能,如文章新闻模块、图片展示、产品列表以及小型的下载功能,还同时增加了邮件订阅等相应模块。公告,友情链接等这些通用功能本程序也同样都集成了!同时本程序引入了模块功能,只要在系统默认模板上创建模块,可以在任何一个语言环境(或任意风格)的适当位置进行使用!

下载
Integer[] originalNumbers = {10, 20, 30};
List numberList = Arrays.asList(originalNumbers);

System.out.println("初始状态 - 列表: " + numberList + ", 数组: " + Arrays.toString(originalNumbers));

// 修改列表中的元素
numberList.set(0, 15);
System.out.println("修改列表后 - 列表: " + numberList + ", 数组: " + Arrays.toString(originalNumbers));
// 输出会显示数组的第一个元素也变成了15: [15, 20, 30]

// 修改数组中的元素
originalNumbers[1] = 25;
System.out.println("修改数组后 - 列表: " + numberList + ", 数组: " + Arrays.toString(originalNumbers));
// 输出会显示列表的第二个元素也变成了25: [15, 25, 30]

从上面的输出可以清晰地看到,无论是修改列表还是修改数组,另一方都会同步更新。这种行为对于需要基于数组进行只读或部分修改(不改变大小)的场景非常方便,但如果你的意图是创建一个完全独立、可自由增删的列表,那么

Arrays.asList
就不是合适的选择。

如果我需要一个可修改的列表,有哪些替代
Arrays.asList
的方法?

当你的需求是创建一个可自由添加、删除元素的列表时,

Arrays.asList
显然就不适用了。不过,Java提供了多种灵活的方式来达到这个目的,每种方法都有其适用场景。

1. 创建一个新的

ArrayList
并传入
Arrays.asList
的结果:

这是最常见也最直接的方法。你可以先用

Arrays.asList
得到一个固定大小的列表,然后将其作为构造参数传递给
java.util.ArrayList
。这样,
ArrayList
会创建一个新的、独立的底层数组来存储这些元素,从而获得一个完全可修改的列表。

String[] items = {"Pen", "Book", "Laptop"};
List mutableList = new ArrayList<>(Arrays.asList(items));

mutableList.add("Keyboard"); // 现在可以添加了
System.out.println("可修改列表: " + mutableList); // 输出: [Pen, Book, Laptop, Keyboard]

mutableList.remove("Pen"); // 也可以删除了
System.out.println("删除后列表: " + mutableList); // 输出: [Book, Laptop, Keyboard]

// 验证与原数组的独立性
items[0] = "Pencil"; // 修改原数组
System.out.println("原数组修改后,可修改列表: " + mutableList); // 输出: [Book, Laptop, Keyboard] (不受影响)

2. 使用

Collections.addAll()
方法:

如果你已经有了一个空的或部分填充的

ArrayList
,并且想从数组中添加所有元素,
Collections.addAll()
是一个简洁的选择。

String[] moreItems = {"Monitor", "Mouse"};
List anotherMutableList = new ArrayList<>();
Collections.addAll(anotherMutableList, moreItems); // 将数组元素添加到列表中

anotherMutableList.add("Webcam");
System.out.println("使用addAll创建的列表: " + anotherMutableList); // 输出: [Monitor, Mouse, Webcam]

3. 使用 Java 8 Stream API:

对于更现代的Java版本(Java 8及更高),Stream API提供了一种声明式的方法来转换数据。你可以将数组转换为流,然后收集到

List
中。

String[] streamItems = {"Cup", "Plate"};
List streamList = Arrays.stream(streamItems)
                                .collect(Collectors.toList());

streamList.add("Spoon");
System.out.println("使用Stream创建的列表: " + streamList); // 输出: [Cup, Plate, Spoon]

这种方式在处理复杂的数据转换或过滤时特别强大。

4. 对于 Java 9+,使用

List.of()
Set.of()
创建不可变列表:

虽然这与你“需要一个可修改的列表”的初衷有点不同,但值得一提。如果你明确知道列表创建后不需要再修改,并且希望它是一个真正的不可变集合,Java 9引入的工厂方法

List.of()
Set.of()
是更好的选择。它们返回的列表是不可变的,尝试修改会抛出
UnsupportedOperationException
,但它们从一开始就明确了这种不可变性,避免了
Arrays.asList
那种容易混淆的固定大小特性。

// 这是不可变的,尝试修改也会报错
// List immutableList = List.of("One", "Two", "Three");
// immutableList.add("Four"); // 抛出 UnsupportedOperationException

选择哪种方法取决于你的具体需求:是需要一个完全可修改的列表,还是一个固定大小的视图,亦或是一个完全不可变的列表。理解这些细微的差别,是高效和正确使用Java集合框架的关键。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

298

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

212

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1500

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

623

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

613

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

588

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

170

2025.07.29

c++字符串相关教程
c++字符串相关教程

本专题整合了c++字符串相关教程,阅读专题下面的文章了解更多详细内容。

83

2025.08.07

Python 自然语言处理(NLP)基础与实战
Python 自然语言处理(NLP)基础与实战

本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

22

2026.01.27

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2.9万人学习

C# 教程
C# 教程

共94课时 | 7.8万人学习

Java 教程
Java 教程

共578课时 | 52.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号