解决使用Arrays.asList()和list的subList()方法时出现的问题

5 篇文章 0 订阅
3 篇文章 0 订阅

目录

Arrays.asList()

List的subList()


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("-------------");


 希望对您有帮助!记得点赞、收藏、关注哦!


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值