使用Arrays.asList报UnsupportedOperationException

本文探讨了使用Arrays.asList方法创建集合时常见的误区,特别是在尝试对返回的列表进行增删改操作时遇到的问题。揭示了该方法返回的ArrayList实例不支持此类操作,并提供了源码解析。

项目场景:

查询多个名销售的销售业绩,上层要求要在查询销售的业绩同事也要查看到每年的年度销售冠军,于是前端传递的是以“,”分割开的字符串。测试的时候就报错java.lang.UnsupportedOperationException的异常


代码展示:

           // 这里隐藏了查询条件,所以就写死了
        List<String>  performId=new ArrayList<>();
        performId.add("701728881476112384");
        performId.add("701728881497083904");
        String[] agentIds = StringUtils.split(agentId, ",");
        List<String> agentIdList = Arrays.asList(agentIds);
        // 后面同事没有注意,就直接展示查询出来就加入
        agentIdList.addAll(performId);

原因分析:

于是我们查看了源码,通过**Arrays.asList(T …a)**创建的 **return new ArrayList<>(a);**以为是java.util包下的,所以就对它增删改了。查看源码发现,该方法并不支持增删改 源码如下:

 private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable{
        private static final long serialVersionUID = -2764017481108945198L;
        private final E[] a;
        ArrayList(E[] array) {
            a = Objects.requireNonNull(array);
        }
        @Override
        public int size() {
            return a.length;
        }
        @Override
        public Object[] toArray() {
            return a.clone();
        }
        @Override
        @SuppressWarnings("unchecked")
        public <T> T[] toArray(T[] a) {
            int size = size();
            if (a.length < size)return Arrays.copyOf(this.a, size,(Class<? extends T[]>) a.getClass());
            System.arraycopy(this.a, 0, a, 0, size);
            if (a.length > size) a[size] = null;
            return a;
        }
        @Override
        public E get(int index) {
            return a[index];
        }
        @Override
        public E set(int index, E element) {
            E oldValue = a[index];
            a[index] = element;
            return oldValue;
        }

        @Override
        public int indexOf(Object o) {
            E[] a = this.a;
            if (o == null) {
                for (int i = 0; i < a.length; i++)
                    if (a[i] == null) return i;
            } else {
              for (int i = 0; i < a.length; i++)
                   if (o.equals(a[i])) return i;
            }
            return -1;
        
        @Override
        public boolean contains(Object o) {
            return indexOf(o) != -1;
        }
        @Override
        public Spliterator<E> spliterator() {
            return Spliterators.spliterator(a, Spliterator.ORDERED);
        }
        @Override
        public void forEach(Consumer<? super E> action) {
            Objects.requireNonNull(action);
            for (E e : a) {
                action.accept(e);
            }
        }
        @Override
        public void replaceAll(UnaryOperator<E> operator) {
            Objects.requireNonNull(operator);
            E[] a = this.a;
            for (int i = 0; i < a.length; i++) {
                a[i] = operator.apply(a[i]);
            }
        }

        @Override
        public void sort(Comparator<? super E> c) {
            Arrays.sort(a, c);
        }
    }
通过以上源码发现,Arrays内部实现的ArrayList并未实现增删改等的操作,继承了 AbstractList.class 类中抛出的 UnsupportedOperationException异常。源码如下:
    ##只粘贴了部分源码,详情可以去AbstractList.class中查看
    public void add(int index, E element) {
        throw new UnsupportedOperationException();
    }

总结:

Arrays.asList(T .....a)不能进行增删改等操作。在使用一下类的时候,看下源码会避免一些代码层的坑。
<think>好的,我现在需要回答用户关于JavaArrays.asListArrays.toString的区别及适用场景的问题。首先,我需要回顾这两个方法的基本概念和用法,确保自己理解正确。 首先,Arrays.asList是用于将数组转换为List集合的方法,但用户提供的引用提到它返回的是Arrays内部的一个静态类ArrayList,而不是java.util.ArrayList。这意味着转换后的List在大小上是固定的,不能添加或删除元素。比如,如果尝试调用add或remove方法会抛出UnsupportedOperationException异常。此外,引用中还提到,如果传入的是基本类型数组,比如int[],Arrays.asList会将整个数组视为单个元素,导致列表大小为1,这可能是一个常见的坑点。 接下来是Arrays.toString,这个方法的作用是将数组转换为字符串表示形式,方便输出和调试。它会将数组元素用逗号分隔,并用方括号括起来,例如"[1, 2, 3]"。这与直接调用数组的toString方法不同,后者通常输出的是对象的哈希码,不够友好。 现在需要明确两者的区别:asList用于转换数组为List,但有一些限制;而toString则是将数组内容格式化为字符串。适用场景方面,当需要将数组作为集合处理,但不需要修改大小时,可以用asList,比如进行迭代或传递给需要集合类型的方法。而toString适用于调试或日志输出,快速查看数组内容。 还需要考虑用户提供的引用中的例子,比如使用基本类型数组时的问题,以及内部类的特性。需要指出asList的注意事项,比如不支持结构修改,以及如何处理对象数组和基本类型数组的不同情况。 总结起来,回答的结构应该先分别介绍两个方法,然后对比它们的用途、返回类型、可变性、适用场景,并给出示例代码说明正确和错误的使用方式。最后,生成相关问题帮助用户进一步理解。</think>### Arrays.asListArrays.toString的区别及适用场景 #### 1. **功能与用途** - **`Arrays.asList`** 将数组转换为**固定大小的List集合**,主要用于将数组适配为集合接口(如`List`),方便调用集合相关方法。 示例: ```java String[] arr = {"A", "B", "C"}; List<String> list = Arrays.asList(arr); // 返回一个固定大小的List ``` 注意:返回的List是`java.util.Arrays.ArrayList`(内部类),**不支持增删操作**,否则抛出`UnsupportedOperationException`[^3][^2]。 - **`Arrays.toString`** 将数组内容格式化为**可读字符串**,用于调试或日志输出。 示例: ```java int[] arr = {1, 2, 3}; System.out.println(Arrays.toString(arr)); // 输出 "[1, 2, 3]" ``` 直接调用数组的`toString()`(如`arr.toString()`)会输出无意义的哈希值(如`[I@1b6d3586`),而`Arrays.toString`会解析元素值[^4]。 --- #### 2. **核心区别** | 特性 | `Arrays.asList` | `Arrays.toString` | |-------------------|------------------------------------------|-----------------------------------| | **返回值类型** | `List<T>`(固定大小) | `String`(数组的字符串表示) | | **是否支持修改** | 仅支持元素修改,不支持增删操作 | 不适用(仅生成字符串) | | **适用场景** | 适配集合接口、遍历或传递集合参数 | 调试输出、日志记录 | | **对基本类型处理** | 会将基本类型数组视为单个元素 | 正确解析基本类型数组元素 | --- #### 3. **典型使用场景** - **使用`Arrays.asList`的情况** - 需要将数组作为集合操作(如遍历、查询): ```java for (String s : Arrays.asList(arr)) { ... } ``` - 适配需要`List`参数的API(如`new HashSet<>(Arrays.asList(arr))`)。 - **使用`Arrays.toString`的情况** - 快速查看数组内容: ```java int[] arr = {1, 2, 3}; System.out.println("数组内容:" + Arrays.toString(arr)); ``` - 调试复杂数据结构(如多维数组需用`Arrays.deepToString`)。 --- #### 4. **常见误区与避坑** - **`Arrays.asList`的陷阱** 1. **基本类型数组问题**: ```java int[] arr = {1, 2, 3}; List<int[]> list = Arrays.asList(arr); // List中仅包含一个元素(整个数组) ``` 需使用包装类型数组: ```java Integer[] arr = {1, 2, 3}; List<Integer> list = Arrays.asList(arr); // 正确 ``` 2. **尝试增删元素**: ```java List<String> list = Arrays.asList("A", "B"); list.add("C"); // 抛出 UnsupportedOperationException ``` - **`Arrays.toString`的替代方案** 直接打印集合时无需调用,因为集合的`toString()`已优化: ```java List<String> list = new ArrayList<>(Arrays.asList("A", "B")); System.out.println(list); // 输出 "[A, B]" ``` --- ### 示例对比 ```java // Arrays.asList 示例 String[] arr = {"A", "B"}; List<String> list = Arrays.asList(arr); // 固定大小List list.set(0, "X"); // 允许修改元素 // list.add("C"); // 错! // Arrays.toString 示例 int[] nums = {1, 2, 3}; System.out.println(Arrays.toString(nums)); // 输出 "[1, 2, 3]" ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值