目录
Arrays.asList()
问题1
不能直接使用 Arrays.asList 来转换基本类型数组,会导致返回的list拿不到数组中的元素
例如:
int[] arr = {1,2,3,4};
List list = Arrays.asList(arr);
System.out.println(list); // [[I@4f8e5cde]
System.out.println(list.size()); // 1
System.out.println(list.get(0).getClass()); // class [I
System.out.println("----------");
原因
Arrays.asList(arr)传入的是一个泛型,相当把int[]类型传入,实际将数组作为了list的元素
解决方法1
// 解决1.1 int[] --> Integer[]
Integer[] arr1 = {1,2,3,4};
List arr1List = Arrays.asList(arr1);
System.out.println(arr1List); // [1, 2, 3, 4]
System.out.println(arr1List.size()); // 4
System.out.println(arr1List.get(0).getClass()); // class java.lang.Integer
System.out.println("----------");
// 解决1.2 stream流方式
int[] arr2 = {1,2,3,4};
List<Integer> arr2List = Arrays.stream(arr2).boxed().collect(Collectors.toList());
System.out.println(arr2List); // [1, 2, 3, 4]
System.out.println(arr2List.size()); // 4
System.out.println(arr2List.get(0).getClass()); // // class java.lang.Integer
System.out.println("=================");
问题2
Arrays.asList 返回的 List 不支持增删操作;原数组和返回的list还有关系,修改任一个的元素都会同步改变
例如:
Integer[] arr3 = {1,2,3,4};
List arr3List = Arrays.asList(arr3);
arr3[1] = 0;
try{
// arr3List.add(5); // 不支持添加 java.lang.UnsupportedOperationException
// arr3List.remove(0);// 不支持删除 java.lang.UnsupportedOperationException
arr3List.set(0,10);
}catch (Exception e){
e.printStackTrace();
}
// [10, 0, 3, 4] 修改了原数组arr3,arr3List也会发生改变
System.out.println(arr3List);
// [10, 0, 3, 4] 对arr3List修改也会影响原来的数组
System.out.println(Arrays.toString(arr3));
System.out.println("----------");
原因
Arrays.asList返回的 List不是java.util.ArrayList,而是 Arrays的内部类 ArrayList。
解决方法2
将Arrays.asList返回list 用java.util.ArrayList包起来
Integer[] arr4 = {1,2,3,4};
List arr4List = new ArrayList(Arrays.asList(arr4));
arr4[1] = 0;
arr4List.set(0,10);
arr4List.add(5);
arr4List.add(6);
arr4List.remove(4);
// [10, 2, 3, 4, 6] arr4List.set(0,10)、arr4List.remove(4)
System.out.println(arr4List);
// [1, 0, 3, 4]
System.out.println(Arrays.toString(arr4));
System.out.println();
List的subList()
问题1
做切片,原list都没有被回收,被sList强引用
例如:
// 做1000次切片,每次重100000个元素的list里切,每次创建的10万个元素list都没有被回收
// 导致内存溢出 java.lang.OutOfMemoryError: Java heap space
List<List<Integer>> data = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
List<Integer> sList = IntStream.rangeClosed(1, 100000).boxed().collect(Collectors.toList());
data.add(sList.subList(0, 1));
}*/
// 删除subList分片后的元素,原list也会同步删除;
// 对原list修改值,同步subList
// 对原list增加删除,分片的sList1异常java.util.ConcurrentModificationException
List<Integer> list1 = IntStream.rangeClosed(1, 10).boxed().collect(Collectors.toList());
List<Integer> sList1 = list1.subList(0, 5);
System.out.println(list1); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
System.out.println(sList1); // [1, 2, 3, 4, 5]
sList1.remove(0);
list1.set(0,111);
System.out.println(list1); // [111, 3, 4, 5, 6, 7, 8, 9, 10]
System.out.println(sList1); // [111, 3, 4, 5]
/*list1.add(11);
System.out.println(list1); // [111, 3, 4, 5, 6, 7, 8, 9, 10, 11]
System.out.println(sList1); // java.util.ConcurrentModificationException*/
System.out.println("-------------");
解决方式 1
new ArrayList<>(list2.subList(0, 5))
List<Integer> list2 = IntStream.rangeClosed(1, 10).boxed().collect(Collectors.toList());
List<Integer> sList2 = new ArrayList<>(list2.subList(0, 5));
System.out.println(list2); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
System.out.println(sList2); // [1, 2, 3, 4, 5]
sList2.remove(0);
list2.set(0,111);
System.out.println(list2); // [111, 2, 3, 4, 5, 6, 7, 8, 9, 10] list2.set(0,111);
System.out.println(sList2); // [2, 3, 4, 5] sList2.remove(0);
list2.add(11);
System.out.println(list2); // [111, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
System.out.println(sList2); // [2, 3, 4, 5]
System.out.println("-------------");
解决方式 1.2
Java 8 使用 Stream 的 skip 和 limit ,同样可用来做分片
List<Integer> list3 = IntStream.rangeClosed(1, 10).boxed().collect(Collectors.toList());
List<Integer> sList3 = list3.stream().skip(0).limit(5).collect(Collectors.toList());
System.out.println(list3); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
System.out.println(sList3); // [1, 2, 3, 4, 5]
sList3.remove(0);
list3.set(0,111);
System.out.println(list3); // [111, 2, 3, 4, 5, 6, 7, 8, 9, 10] list2.set(0,111);
System.out.println(sList3); // [2, 3, 4, 5] sList2.remove(0);
list3.add(11);
System.out.println(list3); // [111, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
System.out.println(sList3); // [2, 3, 4, 5]
System.out.println("-------------");
希望对您有帮助!记得点赞、收藏、关注哦!