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