• 满地坑!细数List的10个坑


    前言

    今天我们主要来说一说List操作在实际使用中有哪些坑,以及面对这些坑的时候我们要怎么解决。

    1. Arrays.asList转换基本类型数组的坑

    在实际的业务开发中,我们通常会进行数组转List的操作,通常我们会使用Arrays.asList来进行转换

    但是在转换基本类型的数组的时候,却出现转换的结果和我们想象的不一致。

    上代码

    1. int[] arr = {1, 2, 3};
    2. List list = Arrays.asList(arr);
    3. System.out.println(list.size());
    4. // 1
    5. 复制代码

    实际上,我们想要转成的List应该是有三个对象而现在只有一个

    1. public static List asList(T... a) {
    2. return new ArrayList<>(a);
    3. }
    4. 复制代码

    可以观察到 asList方法 接收的是一个泛型T类型的参数,T继承Object对象

    所以通过断点我们可以看到把 int数组 整体作为一个对象,返回了一个 List

    那我们该如何解决呢?

    方案一:Java8以上,利用Arrays.stream(arr).boxed()将装箱为Integer数组

    1. List collect = Arrays.stream(arr).boxed().collect(Collectors.toList()); System.out.println(collect.size());
    2. System.out.println(collect.get(0).getClass());
    3. // 3
    4. // class java.lang.Integer
    5. 复制代码

    方案二:声明数组的时候,声明类型改为包装类型

    1. Integer[] integerArr = {1, 2, 3};
    2. List integerList = Arrays.asList(integerArr);
    3. System.out.println(integerList.size()); System.out.println(integerList.get(0).getClass());
    4. // 3
    5. // class java.lang.Integer
    6. 复制代码

    2. Arrays.asList返回的List不支持增删操作

    我们将数组对象转成List数据结构之后,竟然不能进行增删操作了

    1. private static void asListAdd(){
    2. String[] arr = {"1", "2", "3"};
    3. List<String> strings = new ArrayList<>(Arrays.asList(arr));
    4. arr[2] = "4";
    5. System.out.println(strings.toString());
    6. Iterator<String> iterator = strings.iterator();
    7. while (iterator.hasNext()){
    8. if ("4".equals(iterator.next())){
    9. iterator.remove();
    10. }
    11. }
    12. strings.forEach(val ->{
    13. strings.remove("4");
    14. strings.add("3");
    15. });
    16. System.out.println(Arrays.asList(arr).toString());
    17. }
    18. [1, 2, 4]
    19. Exception in thread "main" java.lang.UnsupportedOperationException at java.util.AbstractList.remove(AbstractList.java:161) at java.util.AbstractList$Itr.remove(AbstractList.java:374) at java.util.AbstractCollection.remove(AbstractCollection.java:293) at JavaBase.List.AsListTest.lambda$asListAdd$0(AsListTest.java:47) at java.util.Arrays$ArrayList.forEach(Arrays.java:3880) at JavaBase.List.AsListTest.asListAdd(AsListTest.java:46) at JavaBase.List.AsListTest.main(AsListTest.java:20)
    20. 复制代码

    初始化一个字符串数组,将字符串数组转换为 List,在遍历List的时候进行移除和新增的操作

    抛出异常信息UnsupportedOperationException。

    根据异常信息java.lang.UnsupportedOperationException,我们看到他是从AbstractList里面出来的,让我们进入源码一看究竟

    我们在什么时候调用到了这个 AbstractList 呢?

    其实 Arrays.asList(arr) 返回的 ArrayList 不是 java.util.ArrayList,而是 Arrays的内部类

    1. private static class ArrayList extends AbstractList
    2. implements RandomAccess, java.io.Serializable{
    3. private static final long serialVersionUID = -2764017481108945198L;
    4. private final E[] a;
    5. ArrayList(E[] array) {
    6. a = Objects.requireNonNull(array);
    7. }
    8. @Override
    9. public E get(int index) {}
    10. @Override
    11. public E set(int index, E element) {...}
    12. ...
    13. }
    14. public abstract class AbstractList extends AbstractCollection implements List {
    15. public boolean add(E e) {
    16. add(size(), e);
    17. return true;
    18. }
    19. public void add(int index, E element) {
    20. throw new UnsupportedOperationException();
    21. }
    22. public E remove(int index) {
    23. throw new UnsupportedOperat
  • 相关阅读:
    Windows 10怎么清理磁盘空间?
    java基础10题
    炫酷爱心表白
    【C++和数据结构】模拟实现哈希表和unordered_set与unordered_map
    『吴秋霖赠书活动 | 第二期』《ChatGPT原理与实战》
    计算机专业毕业设计项目推荐09-个人医疗系统(Spring+Js+Mysql)
    json-server工具准备后端接口服务环境
    共享店铺系统开发|干洗店要怎么做共享模式?
    StringBuffer类 和StringBuilder类
    (一)Lenet5 手写数字识别原理及代码解析
  • 原文地址:https://blog.csdn.net/Chenhui98/article/details/126865741