Arrays.asList()的一些注意事项

1. 简介

我们在开发中,经常用Arrays.asList()把一个数组转成一个List集合

String[] arr = {
     "a", "b", "c"};
List<String> list = Arrays.asList(arr);

2. 《阿里巴巴Java 开发手册》的描述

Arrays.asList()将数组转成集合后,底层依然是数组
Arrays.asList()的一些注意事项_第1张图片

3. 注意事项

3.1 传递的数组必须是对象数组,而不是基本类型。

Arrays.asList()是泛型方法,传入的对象必须是对象数组。

int[] arr = {
     1, 2, 3};
List list = Arrays.asList(arr);
System.out.println(list.size());	//1
System.out.println(list.get(0));	//[I@1ef7fe8e 数组对象地址值
System.out.println(list.get(1));	//报错:ArrayIndexOutOfBoundsException
int[] listArr = (int[]) list.get(0);
System.out.println(listArr[0]);		//1
System.out.println(listArr[1]);		//2
System.out.println(listArr[2]);		//3

当传入一个原生数据类型数组时,Arrays.asList()的真正得到的参数就不是数组中的元素,而是数组对象本身!此时List 的唯一元素就是这个数组

使用包装类型数组就可以解决这个问题

Integer[] arr = {
     1, 2, 3};

3.2 使用集合的修改方法:add()remove()clear()会抛出异常

List<Integer> list = Arrays.asList(1, 2, 3);
list.add(4);	//运行时报错:UnsupportedOperationException
list.remove(1); //运行时报错:UnsupportedOperationException
list.clear();   //运行时报错:UnsupportedOperationException

Arrays.asList()方法返回的并不是 java.util.ArrayList,而是java.util.Arrays的一个内部类,这个内部类并没有实现集合的修改方法或者说并没有重写这些方法。

List<Integer> list = Arrays.asList(1, 2, 3);
System.out.println(list.getClass().getName());//java.util.Arrays$ArrayList

下面是java.util.Arrays$ArrayList的简易源码,我们可以看到这个类重写的方法有哪些

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) {
     
         a = Objects.requireNonNull(array);
     }

     @Override
     public int size() {
     
         return a.length;
     }

     @Override
     public Object[] toArray() {
     
         return a.clone();
     }

     @Override
     @SuppressWarnings("unchecked")
     public <T> T[] toArray(T[] a) {
     
         ...
     }

     @Override
     public E get(int index) {
     
         return a[index];
     }

     @Override
     public E set(int index, E element) {
     
         ...
     }

     @Override
     public int indexOf(Object o) {
     
         ...
     }

     @Override
     public boolean contains(Object o) {
     
         return indexOf(o) != -1;
     }

     @Override
     public Spliterator<E> spliterator() {
     
         return Spliterators.spliterator(a, Spliterator.ORDERED);
     }

     @Override
     public void forEach(Consumer<? super E> action) {
     
         ...
     }

     @Override
     public void replaceAll(UnaryOperator<E> operator) {
     
         ...
     }

     @Override
     public void sort(Comparator<? super E> c) {
     
         Arrays.sort(a, c);
     }
 }

再看一下java.util.AbstractListremove()方法

public E remove(int index) {
     
    throw new UnsupportedOperationException();
}

3.3 如何正确的将数组转换为ArrayList?

1. 手动实现

static <T> List<T> arrayToList(final T[] array) {
     
  final List<T> l = new ArrayList<T>(array.length);

  for (final T s : array) {
     
    l.add(s);
  }
  return (l);
}

测试

Integer [] myArray = {
      1, 2, 3 };
System.out.println(arrayToList(myArray).getClass());//class java.util.ArrayList

2. 最简便的方法

List list = new ArrayList<>(Arrays.asList("a", "b", "c"))

3. 使用 Java8 的Stream

Integer [] myArray = {
      1, 2, 3 };
List myList = Arrays.stream(myArray).collect(Collectors.toList());
//基本类型也可以实现转换(依赖boxed的装箱操作)
int [] myArray2 = {
      1, 2, 3 };
List myList = Arrays.stream(myArray2).boxed().collect(Collectors.toList());

4. 使用 Apache Commons Collections

List<String> list = new ArrayList<String>();
CollectionUtils.addAll(list, str);

你可能感兴趣的:(Java基础,java)