Arrays.asList() 和 new ArrayList() 的区别(详解)

简介: Arrays.asList() 和 new ArrayList() 的区别(详解)

Arrays.asList()

源码及分析

package java.util;
public class Arrays {
     /**
     * Returns a fixed-size list backed by the specified array.  (Changes to
     * the returned list "write through" to the array.)  This method acts
     * as bridge between array-based and collection-based APIs, in
     * combination with {@link Collection#toArray}.  The returned list is
     * serializable and implements {@link RandomAccess}.
     *
     * <p>This method also provides a convenient way to create a fixed-size
     * list initialized to contain several elements:
     * <pre>
     *     List&lt;String&gt; stooges = Arrays.asList("Larry", "Moe", "Curly");
     * </pre>
     *
     * @param <T> the class of the objects in the array
     * @param a the array by which the list will be backed
     * @return a list view of the specified array
     */
    @SafeVarargs
    @SuppressWarnings("varargs")
    public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }
    
    /**
     * @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) {
            a = Objects.requireNonNull(array);
        }

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

        @Override
        public Object[] toArray() {
            return a.clone();
        }
        .......
    }
}
  1. Arrays是一个java.util包中的一个类。通过调用asList()这个方法,获取到一个集合,asList()方法中的实现就是new ArrayList();。但是值得注意的是new的这个ArrayList不是java.util包中的ArrayList,而是Arrays中的这个内部类ArrayList。
  2. 内部类java.util.Arrays.ArrayList虽然也是继承了AbstractList这个抽象类,但是它并没有和java.util.ArrayList一样,去实现add()等方法,那这样的话,如果调用add()方法,其实就是调用父类AbstractList类当中的add()方法,但是AbstractList.add()就抛出了异常。
  3. 另外,Arrays.asList()拿到的集合是原本数组的引用,在初始化的java.util.Arrays.ArrayList的时候,将原本的数据存放到一个private并且final的数组中。

AbstractList源码:

/**
     * {@inheritDoc}
     *
     * <p>This implementation always throws an
     * {@code UnsupportedOperationException}.
     *
     * @throws UnsupportedOperationException {@inheritDoc}
     * @throws ClassCastException            {@inheritDoc}
     * @throws NullPointerException          {@inheritDoc}
     * @throws IllegalArgumentException      {@inheritDoc}
     * @throws IndexOutOfBoundsException     {@inheritDoc}
     */
    public E set(int index, E element) {
        throw new UnsupportedOperationException();
    }

    /**
     * {@inheritDoc}
     *
     * <p>This implementation always throws an
     * {@code UnsupportedOperationException}.
     *
     * @throws UnsupportedOperationException {@inheritDoc}
     * @throws ClassCastException            {@inheritDoc}
     * @throws NullPointerException          {@inheritDoc}
     * @throws IllegalArgumentException      {@inheritDoc}
     * @throws IndexOutOfBoundsException     {@inheritDoc}
     */
    public void add(int index, E element) {
        throw new UnsupportedOperationException();
    }

    /**
     * {@inheritDoc}
     *
     * <p>This implementation always throws an
     * {@code UnsupportedOperationException}.
     *
     * @throws UnsupportedOperationException {@inheritDoc}
     * @throws IndexOutOfBoundsException     {@inheritDoc}
     */
    public E remove(int index) {
        throw new UnsupportedOperationException();
    }

测试

public class Test {
    public static void main(String[] args) {
    
        String[] stringArray = new String[]{"A", "B", "C", "D"};
        List<String> stringList = Arrays.asList(stringArray);

        stringList.set(0,"E");

        Arrays.stream(stringArray).forEach((e)-> System.out.println(e));
        System.out.println("--------------");
        stringList.stream().forEach((e)-> System.out.println(e));
       System.out.println("--------------");
        stringList.add("F");
    }
}

结果:
在这里插入图片描述
结论:

  • Arrays.asList 返回的 ArrayList 是一个固定长度(fixed-size)List 对象,只对 Array 进行了包装,返回的是Array的引用(a = Objects.requireNonNull(array);),如list对元素修改,则也会改变Array 的值。
  • 没有实现 add 和 remove等 方法(不支持该操作,若操作后抛异常 java.lang.UnsupportedOperationException)。

new ArrayList()

List<String> list = new ArrayList();

源码及分析

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
 /**
     * Constructs an empty list with the specified initial capacity.
     *
     * @param  initialCapacity  the initial capacity of the list
     * @throws IllegalArgumentException if the specified initial capacity
     *         is negative
     */
    public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }

    /**
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

    /**
     * Constructs a list containing the elements of the specified
     * collection, in the order they are returned by the collection's
     * iterator.
     *
     * @param c the collection whose elements are to be placed into this list
     * @throws NullPointerException if the specified collection is null
     */
    public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();
        if ((size = elementData.length) != 0) {
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // replace with empty array.
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }
}
  1. ArrayList是java.util包中的类,如上述代码所示,ArrayList是继承了AbstractList这个抽象类,并且实现了List接口。
  2. List接口的话,是集合的一个比较重要的接口。这里有一下集合的基本操作方法,比如说add,remove等一系列的操作。AbstractList这个抽象类,虽然实现了List接口,也实现了add,remove等方法,但都只是抛出UnsupportedOperationException()。具体的实现还是看ArrayList类。

测试

public class Test {
    public static void main(String[] args) {
    
        String[] stringArray2 = new String[]{"A", "B", "C", "D"};
        List<String> stringList2 = new ArrayList<>(Arrays.asList(stringArray2));
        stringList2.set(0, "E");

        Arrays.stream(stringArray2).forEach((e) -> System.out.println(e));
        System.out.println("--------------");
        stringList2.add("F");
        stringList2.stream().forEach((e) -> System.out.println(e));

    }

}

结果:
在这里插入图片描述

结论:

  • new ArrayList() 返回的对象,通过源码elementData = Arrays.copyOf(elementData, size, Object[].class);可以看出,list是 Array 中数据拷贝过来的,这个新的 List 与老的 Array 没有关系,对新 List 中数据的操作不会影响到老的 Array 中的数据。
  • ArrayList类实现 add 和 remove等 方法,可动态调整list长度。

主要不同的地方就是在于是否能够对转换后的数组进行元素的添加和删除等常规操作。

目录
相关文章
Arrays.asList、ArrayList.subList使用规范
Arrays.asList、ArrayList.subList使用规范
Arrays.asList之后不要调用修改操作
Arrays.asList之后不要调用修改操作
|
Java API Apache
Arrays.asList():使用指南
Arrays.asList() 是一个 Java 的静态方法,它可以把一个数组或者多个参数转换成一个 List 集合。这个方法可以作为数组和集合之间的桥梁,方便我们使用集合的一些方法和特性。本文将给大家介绍 Arrays.asList() 的语法、应用场景、坑点和总结。
199 0
|
Java C++
List.of() Vs Arrays.asList()
在上面的示例中,List.of() 用于创建不可变的颜色列表。任何通过添加或删除元素来修改列表的尝试都将导致抛出异常。 Arrays.asList() 当我们想要由指定数组支持的固定大小(可序列化)集合时,请使用此方法。对返回集合的任何更改也将写入原始数组。 java
69 0
|
Java
Arrays.asList()方法 讲解
Arrays.asList()方法 讲解
116 0
|
Java 编译器 索引
深入解析Java中的数组复制:System.arraycopy、Arrays.copyOf和Arrays.copyOfRange
当涉及到在Java中处理数组时,有许多方法可供选择,其中一些包括`System.arraycopy()`、`Arrays.copyOf()`和`Arrays.copyOfRange()`。这些方法允许您在不同的数组之间复制数据,但它们之间有一些细微的差异。在本篇博客文章中,我们将深入探讨这些方法,以便您了解何时使用它们以及如何正确使用它们。
525 1
CTO:在项目中使用Arrays.asList、ArrayList.subList,就立马滚
1. 使用Arrays.asList的注意事项 1.1 可能会踩的坑 先来看下Arrays.asList的使用:
|
Java C++ 索引
Arrays.asList() vs Collections.singletonList()
看了 IDEA 的告警: 与 Collections.singletonList 比,使用 Arrays.asList 来生成一个list是否更有优势?后者还能使得返回的list不可变。
146 0
|
Java API
Arrays.asList注意事项
Arrays.asList注意事项