本文共 6872 字,大约阅读时间需要 22 分钟。
1.Arrays.asList(T..)使用的是静态内部类:ArrayList, (没有定义add和remove等一些方法),而不是java.util.ArrayList
/** * 1.测试Arrays.asList()方法 * @author zhangdi * @description * 使用的是静态内部类:ArrayList, (没有定义add和remove等一些方法),而不是java.util.ArrayList * 接受的参数被一个final修饰的成员变量 private final E[] a接受 * 调用Arrays.asList()的add和remove方法 会抛异常:java.lang.UnsupportedOperationException */ @Test public void testAsListOfArray() { Listlist = Arrays.asList("1", "2", "3"); list.add("4"); for (String string : list) { System.out.println("string:" + string); } } @Test public void testAsListOfArray2() { List list = new ArrayList<>(); list.add("5"); list.add("6"); list.add("7"); list.add("8"); for (String string : list) { System.out.println("string:" + string); } }
2.为什么List<int[]> asList2 = Arrays.asList(d);
返回的是List<int[]>
而不是List<int>
呢?为什么testAsListOfArray3
中的list.size():
输出1而不是4呢?
/** * 2.Array.asList()接收基本类型与单个元素 * @author zhangdi * @see https://stackoverflow.com/questions/1467913/arrays-aslist-not-working-as-it-should */ @Test public void testAsListOfArray3(){ //1 int[] f = { 1,2,3,4}; List list = Arrays.asList(f); System.out.println("list.size():"+list.size()); //output: list.size():1 //2 int[] a = { 1,2,3,4,8,10,22,12,214,23}; String[] b = { "a","b","c"}; Integer[] c = { 1,2,3,4,8,10,22,12,214,23}; System.out.println(Arrays.asList(a)); System.out.println(Arrays.asList(b)); System.out.println(Arrays.asList(c)); //3 //There's no such thing as a List in Java - generics don't support primitives. //Autoboxing only happens for a single element, not for arrays of primitives. //java arrays are objects and Arrays.asList() treats your int array as a single argument in the varargs list. int[] d = new int[]{ 1,2,3,4,8,10,22,12,214,23}; Integer[] e = new Integer[]{ 1,2,3,4,8,10,22,12,214,23}; //避免使用原始类型数组作为asList的输入参数 ListasList2 = Arrays.asList(d); List asList3 = Arrays.asList(e); System.out.println(asList2); System.out.println(asList3); // output: /* 1 [[I@232d49d1] //会被当做一个参数接收 [a, b, c] [1, 2, 3, 4, 8, 10, 22, 12, 214, 23] [[I@ef05133d] [1, 2, 3, 4, 8, 10, 22, 12, 214, 23] */ }
因为:Arrays.asList()方法接受一个可变参数T,一般可看做数组参数,但是因为int[] 本身就是一个类型,所以a变量作为参数传递时,编译器认为只传了一个变量,这个变量的类型是int数组,所以size为1,相当于是List中数组的个数。基本类型是不能作为泛型的参数,要想作为泛型化参数就必须使用其对应的包装类型。 按道理此处应该使用包装类型,但这里却没有报错,因为数组是可以泛型化的,所以转换后在list中就有一个类型为int的数组; 所以 ,以后要避免使用原始类型数组作为asList的输入参数.
另外,java8的一些写法:学习一下
//1Integer[] boxedInts = IntStream.of(ints).boxed().toArray(Integer[]::new);ListboxedInts = IntStream.of(ints).boxed().collect(Collectors.toList());//2Integer[] boxedIntArray = Arrays.stream(ints).boxed().toArray(Integer[]::new);List boxedIntList = Arrays.stream(ints).boxed().collect(Collectors.toList());
/** * @author zhangdi * @param strings * @return 目的也是为了让返回的list是一个可操作的list * @description jdk 中Arrays.asList()是一个静态方法: */ @SafeVarargs private staticList asList(T... args) { List list = new ArrayList<>(); for (T a : args) { list.add(a); } return list; }
Arrays.asList()的手写第二个版本(目的也是为了让返回的list是一个可操作的list):
/** * @author zhangdi * @param a * @return * @description asList_v2 比用for更为简洁 */ @SafeVarargs public staticList asList_v2(T... a) { List list = new ArrayList (); Collections.addAll(list, a); return list; }
实际上,addAll底层用的也是for循环,还有一个 result |= c.add(element);操作,可以学习一下
/** * jdk_source: * 把所有指定元素添加到集合c中, 有一个元素添加成功就返回true */ public staticboolean addAll(Collection c, T... elements) { boolean result = false; for (T element : elements) result |= c.add(element); return result; }
jdk源码 – Arrays.asList(T… a) :
从这个内部类ArrayList的实现可以看出,它继承了类AbstractList,但是没有重写add和remove方法,没有给出具体的实现。查看一下AbstractList类中对add和remove方法的定义,如果一个list不支持add和remove就会抛出UnsupportedOperationException。@SafeVarargs @SuppressWarnings("varargs") public staticList asList(T... a) { return new ArrayList<>(a); } /** * @serial include */ private static class ArrayList extends AbstractList 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[] toArray(T[] a) { int size = size(); if (a.length < size) return Arrays.copyOf(this.a, size, (Class ) a.getClass()); System.arraycopy(this.a, 0, a, 0, size); if (a.length > size) a[size] = null; return a; } @Override public E get(int index) { return a[index]; } @Override public E set(int index, E element) { E oldValue = a[index]; a[index] = element; return oldValue; } @Override public int indexOf(Object o) { E[] a = this.a; 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; } @Override public boolean contains(Object o) { return indexOf(o) != -1; } @Override public Spliterator spliterator() { return Spliterators.spliterator(a, Spliterator.ORDERED); } @Override public void forEach(Consumer action) { Objects.requireNonNull(action); for (E e : a) { action.accept(e); } } @Override public void replaceAll(UnaryOperator operator) { Objects.requireNonNull(operator); E[] a = this.a; for (int i = 0; i < a.length; i++) { a[i] = operator.apply(a[i]); } } @Override public void sort(Comparator c) { Arrays.sort(a, c); } }
参考:
转载地址:http://mxwji.baihongyu.com/