Arrays.asList()探讨.md

1.java.util.Arrays.asList()的一般用法

这个方法可以将数组转化为List以进行更加丰富的操作

例如:

String[] str = {"harden","curry"};
List<String> list = Arrays.asList(str);

或者:

List<String> list = Arrays.asList("harden","curry");

2.错误用法和解决方案

1.将基本数据类型的数组作为参数

假设现在需要转换一个整形数组:

int[] str = {1,2,3};
List<String> list = Arrays.asList(str);
list.size()?

如果从错误的角度出发,那么list.size()的值就是3,但是实际上输出的结果是1~~~

接下来追究到asList()方法的签名,

方法签名由方法名和参数的类型和顺序决定,不包括返回值类型

public static <T> List<T> asList(T... a)

注意:这个方法的参数是T,T表示数组元素的class,Class类的对象

所以答案就水落石出了,int,long等基本数据类型是没有对应的class的,这是需要其对应的包装类Integer,Long,所以总结就是asList()方法的参数只能是对象,或者是对象数组,如果数组中是基本数据类型,一定要使用对应的包装类。

正确代码:

public class Test {
   public static void main(String[] args) {
      Integer[] myArray = { 1, 2, 3 };
      List myList = Arrays.asList(myArray);
      System.out.println(myList.size());
   }
}

2.试图修改List的大小

我们知道List集合是可以动态扩容的,和数组不同的地方就是不定长,创建一个List之后可以向其中增加或者删除元素:

String[] str = {"harden","curry"};
List<String> list = Arrays.asList(str);
list.add("paul");

在main方法中运行这段代码后,抛出了java.lang.UnsupportedOperationException异常信息,这说明向list中增加元素的add操作是不被允许的,相同的删除操作也是这样

既然List支持动态扩容,为什么操作失败呢?

查看asList()源码:

@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}

看到new ArrayList<>(),确实产生了一个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;
    }

    //...
}

可以看到,数组a是被final修饰的,相当于一个常量,不能扩充,数组长度直接被写死,需要注意的是,此ArrayList非彼ArrayList,java.util.ArrayList是支持扩容的,但是这个ArrayList是java.util.Arrays里面的一个内部类,这个内部类里面使用final数组来保存元素

解决方法:

1.创建一个真正的ArrayList

public class Test {
   public static void main(String[] args) {
      String[] myArray = { "Apple", "Banana", "Orange" };
      List<String> myList = new ArrayList<String>(Arrays.asList(myArray));
      myList.add("Guava");
   }
}

2.自己造轮子

既然咱用不明白人家的api,就要自己写,可以根据自己的需求,一切DIY

public class Test {
   public static void main(String[] args) {
      String[] myArray = { "Apple", "Banana", "Orange" };
      List<String> myList = new ArrayList<String>();
      for (String str : myArray) {
         myList.add(str);
      }
      System.out.println(myList.size());
   }
}