Arrays.asList

一般情况下,使用Arrays.asList()的原因无非是想将数组或一些元素转为集合,而你得到的集合并不一定是你想要的那个集合

asList在最初设计时用于打印数组,但jdk1.5开始,有了另一个比较更方便的打印函数Arrays.toString(),于是打印不再使用asList(),而asList()恰巧可用于将数组转为集合。

一、首先看几个例子:

(1)将基本类型数组作为asList参数

		String[] strArr = {"A","B","C"};
		List<String> asList = Arrays.asList(strArr);
		System.out.println("封装类型String时:" + asList.size());

		int[] intArr = {1, 2, 3};
		List<String> list = Arrays.asList(intArr);
		System.out.println("基本类型时:" + list.size());

运行结果:

封装类型String时:3
基本类型时:1

(2)将数组作为asList参数后,修改数组或List

		String[] strArr = {"A","B","C"};
		List<String> asList = Arrays.asList(strArr);
		strArr[0] = "a";
		asList.set(1, "b");
		System.out.println(Arrays.toString(strArr));
		System.out.println(asList.toString());

运行结果:

[a, b, C]
[a, b, C]

strArr和asList 中的数据都会改变

(3)数组转换为集合后,进行增删元素

		String[] strArr = {"A","B","C"};
		List<String> asList = Arrays.asList(strArr);
		asList.add("1");
		asList.remove("C");
		System.out.println(asList.toString());

运行结果:

Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.AbstractList.add(AbstractList.java:148)
	at java.util.AbstractList.add(AbstractList.java:108)
	at com.my.tests.TestArrayAsList.main(TestArrayAsList.java:9)

二、深入研究

这里要关注的地方在于:
Arrays.asList()返回的List是:Arrays.ArrayList,而不是java.util.ArrayList
在这里插入图片描述
两者的不同之处:
Arrays.ArrayList是工具类Arrays的一个内部静态类,它没有完全实现List方法,而ArrayList直接实现了List接口,实现了List所有方法。

  • 长度不同和实现的方法不同:
    Arrays.ArrayList是一个定长集合,因为它没有重写add,remove方法,所以,一旦初始化元素后,集合的size就是不可变的。
  • 参数赋值方式不同
    Arrays.ArrayList将外部数组的引用直接通过“=”赋予内部的泛型数组,所以本质指向同一个数组。而ArrayList是将其他集合转为数组后copy到自己内部的数组的。
// 以下是JDK8版本中的Arrays.ArrayList
    public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }
    private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable
    {
        private final E[] a;

        ArrayList(E[] array) {
            a = Objects.requireNonNull(array);	// 此处是直接赋值的,所以本质指向的是同一个数组
     	}
   	}

// 以下是JDK8中java.util.ArrayList
    public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();	// toArray底层使用的是数组clone或System.arraycopy
        if ((size = elementData.length) != 0) {
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // replace with empty array.
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }

在这里插入图片描述

三、案例解析

对于第一个例子:(1)将基本类型数组作为asList参数
由于Arrays.ArrayList参数为可变长泛型,而基本类型是无法泛型化的,所以它把int[] arr数组当成了一个泛型对象,所以集合中最终只有一个元素arr。

对于第二个例子:(2)将数组作为asList参数后,修改数组或List
由于asList产生的集合元素是直接引用作为参数的数组,所以当外部数组或集合改变时,数组和集合会同步变化,这在平时我们编码时可能产生莫名的问题。

对于第三个例子:(3)数组转换为集合后,进行增删元素
由于asList产生的集合并没有重写add,remove等方法,所以它会调用父类AbstractList的方法,而父类的方法中抛出的却是异常信息。

四、支持基础类型的方式

1、如果使用Spring

import org.springframework.util.CollectionUtils;

public class Temp {
	public static void main(String[] args) {
		int[] arr = {1,2,3};
		List list = CollectionUtils.arrayToList(arr);
		System.out.println(list);
	}
}

运行结果:

[1, 2, 3]

2、直接使用Java8

		int intArray[] = {1,2,3};
		List<Integer> iList = Arrays.stream(intArray)
				.boxed()
				.collect(Collectors.toList());
		System.out.println(iList);

运行结果:

[1, 2, 3]

五、数组转ArrayList

1、遍历转换

		Integer intArray[] = {1,2,3};
		ArrayList<Integer> arrayList = new ArrayList<>();
		for (Integer i : arrayList) {
			arrayList.add(i);
		}

2、使用工具类(更加优雅)

		ArrayList<String> list = new ArrayList();
		Collections.addAll(list, "A", "B", "C");

3、对于JAVA8
既可以用于基本类型也可以返回想要的集合。

		int intArray[] = {1,2,3};
		List<Integer> iList = Arrays.stream(intArray)
				.boxed()
				.collect(Collectors.toList());
		System.out.println(iList);

运行结果:

[1, 2, 3]

4、还有另外一种方法
两个集合类结合:将Arrays.asList返回的集合作为ArrayList的构造参数

		ArrayList arrayList = new ArrayList<>(
				Arrays.asList("A", "B", "C")
				);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值