简体   繁体   中英

why list can't be initialized with array, without arrays.aslist()?

Arrays.asList() is declared as below.

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

So, as you know, to initialise a concrete List with an array, you can do this:

String[] strings = new String[] {"hello", "world"};
List<String> list = new ArrayList<>(Arrays.asList(strings));

But what about this?

List<String> list = new ArrayList<>(new String[]{"hello", "world"});

I expected it would works, but didn't.

I understand why. It's because one of the constructors of ArrayList demands Collection class.

Then, what about Arrays.asList() ?

Varargs are compiled as array, so maybe that method would be compiled as below.

public static <T> List<T> asList(T[] a) {
    return new ArrayList<>(a);
}

But it actually returns ArrayList object. Why is this possible?

Indeed, Arrays.asList is implemented as you said , but ArrayList doesn't actually refer to the java.util.ArrayList that we all know and love. It refers to a private inner class in the Arrays class. From the first link, just under the declaration of asList , you will see:

/**
 * @serial include
 */
private static class ArrayList<E> extends AbstractList<E>
    implements RandomAccess, java.io.Serializable
{
    ...

new ArrayList<>(a) is referring to the above class. The above class has a constructor that takes an E[] :

    ArrayList(E[] array) {
        if (array==null)
            throw new NullPointerException();
        a = array;
    }

But the java.util.ArrayList class doesn't have such a constructor, so it is no wonder that you can't do:

List<String> list = new ArrayList<>(new String[]{"hello", "world"});

Another big difference between java.util.ArrayList and java.util.Arrays$ArrayList is that you can add/remove elements to the former, but you can't to the latter. eg This throws an exception:

Arrays.asList("a", "b", "c").add("d");

I absolutely never understood why such a constructor does not exist in java.util.ArrayList to begin with and the decision to name an inner class ArrayList too - is even more interesting. So you are simply looking in the wrong place, nothing more.

They did add such a construct (!= constructor ), but only in java-9 and only to immutable collections:

List<String> list = List.of(new String[]{"one"});

Arrays.asList() is read only collection.

To new ArrayList(...) you have to pass a collection as an argument.

A collection in java is a List, Set

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM