Java Arrays、ArrayList相关坑

Java Arrays、ArrayList相关坑

Arrays坑

循环遍历问题

对数据做循环遍历的时候,不能直接remove、add 操作,否则会报异常

        List<Integer> list = Arrays.asList(1, 2, 3, 4);
        for (Integer i : list) {
            System.out.println(i);
            list.remove(1);
        }

AsList()坑

  • AsList 返回值不支持操作问题,否则会报异常
        List<Integer> list = Arrays.asList(1, 2, 3, 4);
        for (Integer i : list) {
            System.out.println(i);
            list.remove(1);
        }
        list.add(5)

报错UnsupportedOperationException的原因是

    public static <T> List<T> asList(T... a) {
       //返回值是内部ArrayList
        return new ArrayList<>(a);
    }
    //该类未覆盖实现add、remove等操作,默认采用AbstractList,
    //而AbstractList类add、remove等方法会默认抛出UnsupportedOperationException异常
    private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable {
      .........
    }
  • 对原始数组的修改会影响到我们获得的那个 List
        Integer[] a = {1, 2};
        List<Integer> list = Arrays.asList(a);
        for (Integer i : list) {
            System.out.println("未修改数组前数据:" + i);
        }
        System.out.println("---------------------");
        a[0] = 6;
        a[1] =8;
        for (Integer i : list) {
            System.out.println("修改数组后数据:" + i);
        }

结果输出如下:

未修改数组前数据:1
未修改数组前数据:2


修改数组后数据:6
修改数组后数据:8

出现这个原因还和Arrays内部类ArrayList 有关系,通过内部代码发现创建ArrayList时,只是把引用传递给ArrayList类的成员变量a中。
在这里插入图片描述
调整该报错也很简单,就是不要把要传递的数组复制一遍,然后再传递给AsList函数。

ArrayList坑

  • 对数据做循环遍历的时候,不能直接remove、add 操作,否则会报异常
        Integer[] a = {1, 2};
        List<Integer> list = new ArrayList<>(Arrays.asList(a));
        for (Integer i : list) {
            System.out.println("未修改数组前数据:" + i);
            list.add(4);
        }
  • 使用不当 List.subList 可能会导致 OOM
    业务开发时常常要对 List 做切片处理,即取出其中部分元素构成一个新的 List,我们通常会想到使用 List.subList 方法。但,和 Arrays.asList 的问题类似,List.subList 返回的子 List 不是一个普通的 ArrayList。这个子 List 可以认为是原始 List 的视图,会和原始 List 相互影响。如果不注意,很可能会因此产生 OOM 问题。

private static List<List<Integer>> data = new ArrayList<>();

private static void oom() {
   for (int i = 0; i < 1000; i++) {
       List<Integer> rawList = IntStream.rangeClosed(1, 100000).boxed().collect(Collectors.toList());
       data.add(rawList.subList(0, 1));
   }
}

总结

大家在使用ArrayList和Arrays有遇到哪些坑,欢迎大家补充。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值