Java subList、toArray、asList 注意点

1. ArrayList的subList

结果不可以强转成ArrayList,否则抛出ClassCastException异常,原因是subList返回的是ArrayList的内部类SubList,并不是ArrayList,而是ArrayList的一个视图。举例

public class SublistTest {
    public static void main(String[] args) {
        ArrayList<Integer> myList = new ArrayList<Integer>();
        myList.add(1);
        myList.add(2);
        myList.add(3);
        myList.add(4);

        List<Integer> subList = myList.subList(1, 2);

        System.out.println(myList);
        System.out.println(subList);
    }
}

输出

[1, 2, 3, 4]
[2]  

对于subList的操作最终会反映在原列表中,如

public class SublistTest {
    public static void main(String[] args) {
        ArrayList<Integer> myList = new ArrayList<Integer>();
        myList.add(1);
        myList.add(2);
        myList.add(3);
        myList.add(4);

        List<Integer> subList = myList.subList(1, 2);
        subList.add(5);

        System.out.println(myList);
        System.out.println(subList);
    }
}

结果

[1, 2, 5, 3, 4]
[2, 5]

注意对原列表的修改,会导致子列表遍历、增加、删除都会产生ConcurrentModificationException异常,例

public class SublistTest {
    public static void main(String[] args) {
        ArrayList<Integer> myList = new ArrayList<Integer>();
        myList.add(1);
        myList.add(2);
        myList.add(3);
        myList.add(4);

        List<Integer> subList = myList.subList(1, 2);
        myList.add(5);

        System.out.println(myList);
        System.out.println(subList);
    }
}

结果

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$SubList.checkForComodification(ArrayList.java:1237)
    at java.util.ArrayList$SubList.listIterator(ArrayList.java:1097)
    at java.util.AbstractList.listIterator(AbstractList.java:299)
    at java.util.ArrayList$SubList.iterator(ArrayList.java:1093)
    at java.util.AbstractCollection.toString(AbstractCollection.java:454)
    at java.lang.String.valueOf(String.java:2994)
    at java.io.PrintStream.println(PrintStream.java:821)
    at SublistTest.main(SublistTest.java:16)
[1, 2, 3, 4, 5]

2. 集合转数组toArray

建议大小为list.size()。如果小于所需,toArray会重新分配内存空间,并返回数组地址:如果数组元素大于所需,多余的会置为null。举例

public class ToArrayTest {
    public static void main(String[] args) {
        List<Integer> myList = new ArrayList<Integer>();
        myList.add(1);
        myList.add(2);
        myList.add(3);

        Integer[] myArray = new Integer[myList.size()];
        myList.toArray(myArray);

        System.out.println(myList);
        System.out.println(myArray.length);
    }
}

结果

[1, 2, 3]
3

注:如果直接用无参数的list.toArray(),返回的是Object[]类,若强制转化成数组会出现ClassCastException异常

3. 使用asList把数组转化成集合

不要对得到的结果进行增、删操作,否则会抛出UnsupportedOperationException异常,例

public class AsListTest {
    public static void main(String[] args) {
        Integer[] myArray = new Integer[] {1, 2, 3};
        List<Integer> myList = Arrays.asList(myArray);
        myList.add(2);
//        myList.remove(4);
    }
}

结果

Exception in thread "main" java.lang.UnsupportedOperationException
    at java.util.AbstractList.add(AbstractList.java:148)
    at java.util.AbstractList.add(AbstractList.java:108)
    at AsListTest.main(AsListTest.java:9)

原因:asList返回的是Arrays的内部类,并没有实现集合的修改方法,只是体现的适配器模式,只是转换接口,后台其实还是数组,这样对数据进行增删肯定是不行的。既然后台是数组,那么对元素的修改还是可以的,如

public class AsListTest {
    public static void main(String[] args) {
        Integer[] myArray = new Integer[] {1, 2, 3};
        List<Integer> myList = Arrays.asList(myArray);
//        myList.add(2);
//        myList.remove(4);
        myArray[1] = 5;
        System.out.println(myArray[1]);
        System.out.println(myList.get(1));
    }
}

结果

5
5

 

posted @ 2018-03-03 12:24  jihite  阅读(699)  评论(0编辑  收藏  举报