关于数组和List之间相互转换的方法

本文详细介绍了如何在Java中将List转换为数组,以及如何将数组转换为List,包括使用ArrayList的toArray方法和Arrays.asList方法的具体应用和注意事项。

1.List转换成为数组。(这里的List是实体是ArrayList)

调用ArrayList的toArray方法。

toArray

public T[] toArray(T[] a)返回一个按照正确的顺序包含此列表中所有元素的数组;返回数组的运行时类型就是指定数组的运行时类型。如果列表能放入指定的数组,则返回放入此列表元素的数组。否则,将根据指定数组的运行时类型和此列表的大小分配一个新的数组。

如果指定的数组能容纳列表并有剩余空间(即数组的元素比列表的多),那么会将数组中紧跟在集合末尾的元素设置为 null。这对确定列表的长度很有用,但只 在调用方知道列表中不包含任何 null 元素时才有用。

指定者:

接口 Collection 中的 toArray

指定者:

接口 List 中的 toArray

覆盖:

类 AbstractCollection 中的 toArray

参数:

a - 要存储列表元素的数组,如果它足够大的话;否则,它是一个为存储列表元素而分配的、具有相同运行时类型的新数组。

返回:

包含列表元素的数组。

抛出:

ArrayStoreException - 如果 a 的运行时类型不是此列表中每个元素的运行时类型的超类型。
具体用法:

List list = new ArrayList(); 

list.add("1"); 

list.add("2"); 

final int size = list.size(); 

String[] arr = (String[])list.toArray(new String[size]);

2.数组转换成为List

调用Arrays的asList方法.

JDK 1.4对java.util.Arrays.asList的定义,函数参数是Object[]。所以,在1.4中asList()并不支持基本类型的数组作参数。

 JDK 1.5中,java.util.Arrays.asList的定义,函数参数是Varargs, 采用了泛型实现。同时由于autoboxing的支持,使得可以支持对象数组以及基本类型数组。

 不过在使用时,当传入基本数据类型的数组时,会出现小问题,会把传入的数组整个当作返回的List中的第一个元素,例如:

public static void main(String[] args){
    int[] a1 = new int[]{1,2,3};
    String[] a2 = new String[]{"a","b","c"};
      
    System.out.println(Arrays.asList(a1));
    System.out.println(Arrays.asList(a2));
}
  1. 打印结果如下:
1
2 [[I@dc8569]
[a, b, c] 

下面说说Arrays.asList()的返回值:

JDK文档是这么说的:
public static <T> List<T> asList(T... a) 返回一个受指定数组支持的固定大小的列表。(对返回列表的更改会“直接写”到数组。)此方法同 Collection.toArray() 一起,充当了基于数组的 API 与基于 collection 的 API 之间的桥梁。返回的列表是可序列化的,并且实现了 RandomAccess。此方法还提供了一个创建固定长度的列表的便捷方法,该列
/**
 * @serial include
 */
 private static class ArrayList<E>extends AbstractList<E>implements RandomAccess, java.io.Serializable {
     private static final long serialVersionUID = -2764017481108945198L;
     private final E[] a;
  
     ArrayList(E[] array) {
         if (array == null)
         throw new NullPointerException();
         a = array;
     }
      
     public int size() {
        return a.length;
     }
      
     public Object[] toArray() {
        return a.clone();
     }
      
     public <T> T[] toArray(T[] a) {
         int size = size();
         if (a.length < size)
            return Arrays.copyOf(this.a, size, (Class<? extends T[]>) a.getClass());
         System.arraycopy(this.a,0, a, 0, size);
         if (a.length > size)
            a[size] = null;
         return a;
     }
      
     public E get(int index) {
        return a[index];
     }
      
     public E set(int index, E element) {
         E oldValue = a[index];
         a[index] = element;
         return oldValue;
     }
      
     public int indexOf(Object o) {
         if (o == null) {
             for (int i = 0; i < a.length; i++)
             if (a[i] == null)
             return i;
         }else {
             for (int i = 0; i < a.length; i++)
             if (o.equals(a[i]))
             return i;
         }
         return -1;
     }
      
     public boolean contains(Object o) {
        return indexOf(o) != -1;
     }
}

 
表被初始化为包含多个元素: List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");

我们都知道,List的一个典型的特性就是其长度是可变的,我们可以很方便地对它进行插入和删除元素的操作,这是它与数组所存在的一个很大的区别,后者的长度是固定的,而且我们不能从数组中删除元素,只能修改元素的值。利用Arrays.asList(array)将返回一个List,然而这个返回的List并不支持add和remove的操作。

这是什么原因呢?

Arrays.asList源码:

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

这里的ArrayList并不是java.util.ArrayList,而是Arrays的内部类:

我们可以看到该内部类继承的是AbstractList,下面是AbstractList的add和remove方法源码:

public boolean add(E e) {
    add(size(), e);
    return true;
}
  
public void add(int index, E element) {
    throw new UnsupportedOperationException();
}
  
public E remove(int index) {
    throw new UnsupportedOperationException();
}

所以,当我们对Arrays.asList返回的List进行添加或删除时将会报 java.lang.UnsupportedOperationException 异常。

<think>好的,我现在需要帮助用户解决关于数组List之间互相转换的问题。用户已经提供了一些引用资料,我需要仔细阅读并理解这些引用内容,然后整理出正确的转换方法。 首先,引用[1]提到数组List方法有遍历、Arrays.asList()、Collections.addAll()Java8的Stream流。但需要注意的是Arrays.asList()返回的List是固定大小的,不能进行添加或删除操作,这一点在引用[3]中也有说明,使用不当会抛出UnsupportedOperationException。所以,如果用户需要一个可变的List,可能需要使用Collections.addAll()或者通过Stream来处理。 引用[2]提到int数组List转换比较麻烦,可能需要使用Stream API。对于基本类型数组如int[],直接使用Arrays.asList()会将整个数组作为单个元素处理,因此必须使用Stream的boxed()方法转换为包装类型,例如Integer,然后再收集为List。这可能是用户需要注意的一个点,特别是处理基本数据类型时。 引用[3]再次强调了Arrays.asList()的局限性,并提醒不要进行结构性修改操作。这需要我在回答中明确指出,避免用户踩坑。 引用[4]讨论了STL容器vector的转换,但用户的问题主要是Java相关的,这部分可能不太相关,但可以暂时忽略。 接下来,我需要将数组ListList数组方法分步骤整理出来,确保涵盖各种情况,包括基本类型引用类型,同时指出注意事项。 对于数组List: 1. 使用Arrays.asList()方法,但结果不可变,适用于不需要修改的情况。 2. 使用Collections.addAll()结合ArrayList构造函数,创建一个可变的List。 3. 使用Java8的Stream流处理,特别是基本类型数组需要先装箱。 对于List数组: 1. 使用toArray()方法,但返回的是Object[],可能需要类型转换。 2. 使用toArray(T[] a)方法,推荐指定类型数组,避免类型问题。 3. 对于基本类型如int,可能需要手动遍历或使用Stream处理。 此外,要特别注意基本类型数组包装类型List之间转换,比如int[]List<Integer>,这需要额外处理,不能直接用Arrays.asList(),因为自动装箱的问题。 用户提供的示例代码中,引用[2]提到int数组List需要调用Arrays.stream(),而List数组则使用Stream。例如,int数组List<Integer>可以通过Stream的boxed()方法实现,而List<Integer>转int数组则需要mapToInt()处理。 最后,我需要总结这些方法,并指出在不同场景下的适用性注意事项,确保用户能够根据具体需求选择正确的方法,同时避免常见的错误,如尝试修改由Arrays.asList()返回的List。</think>### 数组List互相转换的实现方式 #### 一、数组List的常用方法 1. **`Arrays.asList()`方法(固定大小列表)** - 适用于引用类型数组(如`String[]`、`Integer[]`),但返回的List**不可修改结构**(不能增删元素)[^3] - 示例: ```java String[] arr = {"A", "B"}; List<String> list = Arrays.asList(arr); // list.add("C")会报错 ``` 2. **`Collections.addAll()`创建可变List** - 通过`new ArrayList<>()`构造可变容器,避免固定大小限制[^1] - 示例: ```java String[] arr = {"A", "B"}; List<String> list = new ArrayList<>(); Collections.addAll(list, arr); // 可执行add/remove操作 ``` 3. **Java8 Stream处理基本类型数组** - 针对`int[]`等基本类型数组,需先转换为包装类型流[^2] - 示例: ```java int[] intArr = {1,2,3}; List<Integer> list = Arrays.stream(intArr) .boxed() .collect(Collectors.toList()); ``` --- #### 二、List数组的常用方法 1. **`toArray()`无参方法** - 返回`Object[]`数组,需强制类型转换[^1] - 示例: ```java List<String> list = Arrays.asList("A", "B"); String[] arr = (String[]) list.toArray(); // 注意类型安全 ``` 2. **`toArray(T[] a)`推荐方法** - 指定目标数组类型,避免类型转换问题[^1] - 示例: ```java List<String> list = Arrays.asList("A", "B"); String[] arr = list.toArray(new String[0]); ``` 3. **处理基本类型数组** - 若需要将`List<Integer>`转为`int[]`,需手动处理[^2] - 示例: ```java List<Integer> list = Arrays.asList(1,2,3); int[] intArr = list.stream() .mapToInt(Integer::intValue) .toArray(); ``` --- #### 三、注意事项 1. **固定大小问题** `Arrays.asList()`生成的List底层由数组支持,调用`add()`或`remove()`会抛出`UnsupportedOperationException`[^3] 2. **基本类型处理** `Arrays.asList(new int[]{1,2,3})`会将整个数组视为单个元素,必须使用包装类型或Stream处理[^2] 3. **线程安全性** 使用`Collections.synchronizedList()`可创建线程安全的List,但转换过程本身不保证线程安全[^4] --- ### 典型场景选择 | 场景 | 推荐方法 | |------|----------| | 引用类型数组转可变List | `new ArrayList<>(Arrays.asList(arr))` | | 基本类型数组List | `Arrays.stream(intArr).boxed().collect(...)` | | List转类型安全数组 | `list.toArray(new T[0])` |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值