Home  >  Article  >  Java  >  Java Improvement Chapter (36) -----Java Collection Details (2): Defects of asList

Java Improvement Chapter (36) -----Java Collection Details (2): Defects of asList

黄舟
黄舟Original
2017-02-11 10:33:481356browse

In the actual development process, we often use asList to convert an array into a List. This method is very convenient to use, but the asList method has several flaws:

1. Avoid using basic data type arrays to convert to lists

      There is a more interesting flaw when using 8 basic type arrays to convert to lists. Let’s look at the following program first:

##

public static void main(String[] args) {
        int[] ints = {1,2,3,4,5};
        List list = Arrays.asList(ints);
        System.out.println("list'size:" + list.size());
    }
    ------------------------------------
    outPut:
    list'size:1

The running result of the program is not 5 as we expected. It’s an outrageous 1. What’s going on? Let’s look at the source code first:

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

The parameter accepted by asList is a generic variable-length parameter, we know Basic data types cannot be styled, which means that the 8 basic types cannot be used as parameters of asList. If they want to be used as generic parameters, their corresponding packaging types must be used. But why did nothing go wrong in this instance? Because this instance uses an array of type int as its parameter, and an array is an object in Java, it can be genericized. So this example will not produce errors. Since the example uses the entire int type array as a generic parameter, there will be only one int list after asList conversion. As follows:

public static void main(String[] args) {
    int[] ints = {1,2,3,4,5};
    List list = Arrays.asList(ints);
    System.out.println("list 的类型:" + list.get(0).getClass());
    System.out.println("list.get(0) == ints:" + list.get(0).equals(ints));
}
--------------------------------------------
outPut:
list 的类型:class [I
list.get(0) == ints:true

From this running result, we can fully prove that the elements in the list are int arrays. Once you understand this, the modification method will be clear at a glance: change int to Integer.

public static void main(String[] args) {
        Integer[] ints = {1,2,3,4,5};
        List list = Arrays.asList(ints);
        System.out.println("list&#39;size:" + list.size());
        System.out.println("list.get(0) 的类型:" + list.get(0).getClass());
        System.out.println("list.get(0) == ints[0]:" + list.get(0).equals(ints[0]));
    }
    ----------------------------------------
    outPut:
    list&#39;size:5
    list.get(0) 的类型:class java.lang.Integer
    list.get(0) == ints[0]:true

##>>>>>>Java details (2.1): When using asList Don't use primitive data types as parameters.

2. The list generated by asList is not operable

We will make another small modification to the above example:

public static void main(String[] args) {
        Integer[] ints = {1,2,3,4,5};
        List list = Arrays.asList(ints);
        list.add(6);
    }

This example is about converting ints into list categories through asList, and then adding an element through the add method. This example couldn't be simpler, but what about the running results? Type what we expected:

Exception in thread "main" java.lang.UnsupportedOperationException
    at java.util.AbstractList.add(Unknown Source)
    at java.util.AbstractList.add(Unknown Source)
    at com.chenssy.test.arrayList.AsListTest.main(AsListTest.java:10)

The running result throws an UnsupportedOperationException, which indicates that the list is not supported add method. This makes us depressed. How could list not support the add method? Is jdk's brain blocked? Let’s look at the source code of asList again:

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

After asList accepts the parameters, directly create a new ArrayList, go here There should be no errors, right? Don't worry, look down:

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) {
            if (array==null)
                throw new NullPointerException();
            a = array;
        }
        //.................
    }

         

This is the source code of ArrayList, we can see it from here Out, this ArrayList is not java.util.ArrayList, it is an internal class of Arrays. This internal class provides size, toArray, get, set, indexOf, and contains methods, and methods such as add and remove to change the list results are inherited from the AbstractList parent class. At the same time, these methods are also quite strange. It directly throws an UnsupportedOperationException exception:

public boolean add(E e) {
        add(size(), e);
        return true;
    }
    
    public E set(int index, E element) {
        throw new UnsupportedOperationException();
    }
    
    public void add(int index, E element) {
        throw new UnsupportedOperationException();
    }
    
    public E remove(int index) {
        throw new UnsupportedOperationException();
    }

Through these codes, we can see that the list returned by asList is just a cloak of list. , it does not have the basic characteristics of list (variable length). The list is a list of immutable length. The returned list can only be as long as the array of parameters passed in. So:

>>>>>>Java details (2.2): Don't try to change the list returned by asList, otherwise you will suffer the consequences.

The above is the content of Java Improvement Chapter (36) -----Java Collection Details (2): Defects of asList , for more related content, please pay attention to the PHP Chinese website (www.php.cn)!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn