Java中Arrays类的一些坑

本文详细解析了Java中Arrays.asList方法在处理数组时的限制,包括不可添加元素、固定大小、基本类型数组转换问题等,并提供了多种解决方案,如新建ArrayList、使用Collections.addAll或Stream API。同时强调了Arrays.asList与原始数组之间的共享性,可能导致的意外修改问题。最后,介绍了Java 8中如何将基本类型数组转换为List。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通过asList返回的固定大侠的List不支持添加元素

代码

public static void main(String[] args) {
        String[] arr = new String[]{"aa", "bb"};
        List<String> list = Arrays.asList(arr);
        list.add("cc");
    }

执行结果

Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.AbstractList.add(AbstractList.java:148)
	at java.util.AbstractList.add(AbstractList.java:108)
	at Test.main(Test.java:8)

原因是 java.util.Arrays.ArrayList 类实现了 set(), get(),contains()方法,但是并没有实现增加元素的方法(事实上是可以调用 add 方法,但是没有具体实现,仅仅抛出 UnsupportedOperationException 异常),因此它的大小也是固定不变的。可以通过set方法进行设置值,默认长度是10。

解决方案

新建一个ArrayList

代码:

public static void main(String[] args) {
        String[] arr = {"aa", "bb", "cc"};
        List<String> list = Arrays.asList(arr);
        ArrayList<String> strings = new ArrayList<>(list);
        strings.add("dd");
        System.out.println(strings.toString());
    }

执行结果:

[aa, bb, cc, dd]

通过集合工具类Collections.addAll()方法(最高效,推荐)

通过Collections.addAll(arrayList, strArray)方式转换,根据数组的长度创建一个长度相同的List,然后通过Collections.addAll()方法,将数组中的元素转为二进制,然后添加到List中,这是最高效的方法。

代码:

public static void main(String[] args) {
        String[] arr = {"aa", "bb", "cc"};
        ArrayList<String> strings = new ArrayList<>(arr.length);
        Collections.addAll(strings, arr);
        strings.add("dd");
        System.out.println(strings.toString());
    }

执行结果:

[aa, bb, cc, dd]

Stream优雅的写法

代码:

public static void main(String[] args) {
        String[] arr = {"aa", "bb", "cc"};
        List<String> list = Stream.of(arr).collect(Collectors.toList());
        list.add("dd");
        System.out.println(list.toString());
    }

执行效果:

[aa, bb, cc, dd]

底层先将数组转换为流,再使用addAll()的方式,执行效率次于Collections.addAll()方式,但是写法优雅呀。

对原始数组的修改会影响到我们获得的那个 List

代码

 public static void main(String[] args) {
        String[] arr = {"aa", "bb", "cc"};
        List<String> list = Arrays.asList(arr);
        arr[1] = "dd";
        System.out.printf("arr:%s list:%s", Arrays.toString(arr), list);
    }

执行结果

arr:[aa, dd, cc] list:[aa, dd, cc]

原因是Arrays内部类ArrayList其实是直接使用了原始的数组,把通过 Arrays.asList 获得的 List 交给其他方法处理,很容易因为共享了数组,相互修改产生 Bug。

不能直接使用 Arrays.asList 来转换基本类型数组

代码

public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        List list = Arrays.asList(arr);
        System.out.println(list.size());
    }

执行结果

1

原因是asList 方法的参数必须是对象或者对象数组,而原生数据类型不是对象,当传入一个原生数据类型数组时,asList 的真正得到的参数就不是数组中的元素,而是数组对象本身。

解决方案

Java8可通过stream流将3种基本类型数组转为List

如果JDK版本在1.8以上,可以使用流stream来将下列3种数组快速转为List,分别是int[]long[]double[],其他数据类型比如short[]byte[]char[],在JDK1.8中暂不支持。

代码:

public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        List<Integer> list = Arrays.stream(arr).boxed().collect(Collectors.toList());
        System.out.println(list);
    }

执行效果:

[1, 2, 3]

Reference

  1. Arrays.asList注意事项
  2. Java 中初始化 List 集合的 6 种方式!
  3. Arrays.toList() 和Collections.singletonList()的区别

原文地址:https://jonssonyan.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值