数组和List之间的相互转换

数组和列表(List)在Java中是常用的数据结构,它们各自有不同的优点:数组大小固定,访问速度快;列表大小可变,使用更灵活。在实际开发中,我们经常需要在两者之间进行转换。以下是如何在数组和列表之间进行相互转换的详细方法、源码分析以及代码演示。

从数组到List

要将数组转换为列表,可以使用 Arrays.asList(T... a) 方法。它返回一个固定大小的列表。这个列表是一个适配器,它直接映射到原始数组上。来看下面的代码示例和解释。

代码演示:

java 复制代码
import java.util.Arrays;
import java.util.List;

public class ConversionDemo {
    public static void main(String[] args) {
        String[] array = {"Apple", "Banana", "Cherry"};
        List<String> list = Arrays.asList(array);

        System.out.println(list);
    }
}

源码分析:

Arrays.asList() 是一个泛型方法,内部实现大致如下:

java 复制代码
public class Arrays {
    // ... 省略其他代码 ...

    public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }

    // ... 省略其他代码 ...

    private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable {
        private final E[] a;

        ArrayList(E[] array) {
            a = Objects.requireNonNull(array);
        }

        // ... 实现 AbstractList 的各种方法 ...
    }
}

这个内部的 ArrayList 类(注意,这不是 java.util.ArrayList)是一个固定大小的列表视图,它直接引用了传入的数组。当你尝试对这个列表执行添加或删除操作时,会抛出 UnsupportedOperationException

从List到数组

要将列表转换为数组,可以使用 List 接口的 toArray() 方法。这个方法有两个版本:一个返回 Object[],另一个可以返回更具体类型的数组。

代码演示:

java 复制代码
import java.util.ArrayList;
import java.util.List;

public class ConversionDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Apple");
        list.add("Banana");
        list.add("Cherry");

        // 无参版本,返回 Object[]
        Object[] objectArray = list.toArray();

        // 有参版本,返回 String[]
        String[] stringArray = list.toArray(new String[0]);

        System.out.println(Arrays.toString(objectArray));
        System.out.println(Arrays.toString(stringArray));
    }
}

源码分析:

ArrayList 中的 toArray() 方法本质上调用了 System.arraycopy() 来复制列表中的元素到数组中。

java 复制代码
public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, Serializable {
    // ... 省略其他代码 ...

    public <T> T[] toArray(T[] a) {
        if (a.length < size) {
            // 如果传入数组大小不足,会创建一个新的数组实例
            return (T[]) Arrays.copyOf(elementData, size, a.getClass());
        }
        System.arraycopy(elementData, 0, a, 0, size);
        if (a.length > size) {
            a[size] = null;
        }
        return a;
    }

    // ... 省略其他代码 ...
}

在使用 toArray(T[] a) 时,如果传入的数组大于或等于列表的大小,就会在传入的数组上直接进行元素复制。如果传入的数组小于列表的大小,则会在内部创建一个新的数组,类型为传入数组的类型,并返回。

注意细节

在进行数组和列表之间的转换时,以下是一些需要特别注意的细节:

  1. 类型一致性 :使用 toArray(T[] a) 方法时,传入数组的类型应与列表元素的类型相匹配,否则会抛出 ArrayStoreException
  2. 列表的固定大小Arrays.asList() 返回的列表尺寸是固定的,不能增加或减少元素。
  3. 数组的固定大小 :数组一旦创建大小固定,转换为列表后,如果需要动态改变大小,需要转换为 ArrayList
  4. 效率问题:转换操作是有成本的,特别是在列表到数组的转换中,可能涉及到数组的复制。如果性能是一个考虑点,这个成本需要被考虑进去。
  5. 空元素的处理 :在将列表转换为数组时,如果传入的数组比列表大小要大,多出来的数组位置将被设置为 null

综上所述,数组和列表之间的转换是Java编程中的一个基本操作,理解它们的内在机制对于编写高效和可靠的代码非常重要。通过上述示例和解释,你应该对如何进行这些转换有了深入的理解。

相关推荐
月落归舟13 小时前
Redis 三种消息队列实现方案
数据库·redis·list
辛苦才能3 天前
C++ list深度解析:迭代器的类封装设计与反向迭代器的镜像原理
c++·list
我命由我123454 天前
Java 开发 - List subList 方法
java·windows·操作系统·list·intellij-idea·idea·intellij idea
Hommy884 天前
【剪映小助手】字符串列表转对象接口(Str List To Obds)
数据结构·list·剪映小助手·视频剪辑自动化·剪映api·开源剪映小助手
程序员-Benothing5 天前
Java集合:List实现类深度对比
java·开发语言·后端·面试·list
木木子225 天前
# 鸿蒙 ArkTS 实战:秒表 Stopwatch(示例 5)
数据结构·华为·list·harmonyos
鱼子星_7 天前
【C++】深入剖析list:list及其双向迭代器实现
开发语言·数据结构·c++·笔记·stl·list
啊啊啊啊啊!!!!8 天前
【c++】手撕STL List:从接口使用到底层双向链表的实现
c++·链表·list
程序喵大人11 天前
【C++进阶】STL容器与迭代器 - 04 list 和 forward_list 用节点换稳定位置
开发语言·c++·list
2301_7681034916 天前
HarmonyOS趣味相机实战第31篇:图片文档List、详情弹层与删除状态闭环
list·harmonyos·arkts·状态管理·arkui