Java集合与数组的转换

数组转化为集合

使用Arrays.asList包装器可以达到这个目的。

public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}
如上所示,函数参数是Varargs(可变参数), 采用了泛型实现。同时由于autoboxing的支持,使得可以支持对象数组以及基本类型数组。

不过在使用时,当传入基本数据类型的数组时,会出现小问题,会把传入的数组整个当作返回的List中的第一个元素,例如:

int[] arr1 = new int[]{111, 222, 333};
String[] arr2 = new String[]{"111", "222", "333"};
System.out.println(Arrays.asList(arr1));
System.out.println(Arrays.asList(arr2));
输出:

[[I@45ee12a7]
[111, 222, 333]

验证:

int[] arr1 = new int[]{111, 222, 333};
List list = Arrays.asList(arr1);
System.out.println("list.size() = " + list.size());
int[] arr3 = (int[]) list.get(0);
System.out.println(Arrays.toString(arr3));

利用1.8特性,也是可以实现转换的:

int[] arr1 = {111, 222, 333};
List<Integer> list = IntStream.of(arr1).boxed().collect(Collectors.toList());
list.forEach(System.out::println);

asList

public static <T> List<T> asList(T... a)
返回一个受指定数组支持的固定大小的列表。(对返回列表的更改会“直接写”到数组。)此方法同 Collection.toArray() 一起,充当了基于数组的 API 与基于 collection 的 API 之间的桥梁。返回的列表是可序列化的,并且实现了 RandomAccess

此方法还提供了一个创建固定长度的列表的便捷方法,该列表被初始化为包含多个元素:

     List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
 

参数:
a - 支持列表的数组。
返回:
指定数组的列表视图。

利用Arrays.asList(array)将返回一个List(列表视图),然而这个返回的List并不支持add和remove的操作。

有个很有意思的tip:<T>与T的区别?

其实和变量先声明再使用本质上是相同的。

返回的List是在Arrays内部定义的:

private static class ArrayList<E> extends AbstractList<E>
    implements RandomAccess, java.io.Serializable
{...}

在AbstractList中查看add和remove方法:

public void add(int index, E element) {
    throw new UnsupportedOperationException();
}
public E remove(int index) {
    throw new UnsupportedOperationException();
}
所以,当我们对Arrays.asList返回的List进行添加或删除时将会报 java.lang.UnsupportedOperationException 异常。

如果想执行添加/删除操作,我们可以以此创建新的List

String[] arr1 = {"111", "222", "333"};
List<String> list = new ArrayList<>(Arrays.asList(arr1));
list.add("444");
list.forEach(System.out::println);

而当我们对其中一个做更新操作时,另一个会同时更新。这是视图的特性

String[] arr1 = {"111", "222", "333"};
List<String> list = Arrays.asList(arr1);
arr1[0] = "11";
list.set(1, "22");
list.forEach(s -> System.out.print(s + " "));
System.out.println("\n" + Arrays.toString(arr1));
输出:

11 22 333 
[11, 22, 333]


集合转化为数组

使用集合中的toArray方法可以实现以上目的。
List集合中toArray的两个方法:
Object[] toArray();
<T> T[] toArray(T[] a);
但是我们却不能这样使用:
List<String> list = new ArrayList<>();
list.add("111");
list.add("222");
list.add("333");
list.forEach(System.out::println);
String[] arr = (String[]) list.toArray();
会报ClassCastException异常。
实际上,必须使用toArray方法的一个变体形式。
List<String> list = new ArrayList<>();
list.add("111");
list.add("222");
list.add("333");
list.forEach(System.out::println);
String[] arr = list.toArray(new String[0]);
System.out.println(Arrays.toString(arr));
这样一来,返回的数组就会创建为相同的数组类型。(toArray(new String[x]),x小于size则创建新的数组并返回,大于等于则返回你创建的,当然大于的那一部分初始化null)
String[] arr = list.toArray(new String[list.size()]);
在这种情况下,不会创建新数组。
当然,也可以这样:
String[] arr1 = Arrays.copyOf(list.toArray(), list.size(), String[].class);
System.out.println(Arrays.toString(arr1));
有点曲线救国的味道。

toArray

Object[] toArray()
返回包含此 collection 中所有元素的数组。如果 collection 对其迭代器返回的元素顺序做出了某些保证,那么此方法必须以相同的顺序返回这些元素。

返回的数组将是“安全的”,因为此 collection 并不维护对返回数组的任何引用。(换句话说,即使 collection 受到数组的支持,此方法也必须分配一个新的数组)。因此,调用者可以随意修改返回的数组。

此方法充当了基于数组的 API 与基于 collection 的 API 之间的桥梁。

返回:
包含此 collection 中所有元素的数组

toArray

<T> T[] toArray(T[] a)
返回包含此 collection 中所有元素的数组;返回数组的运行时类型与指定数组的运行时类型相同。如果指定的数组能容纳该 collection,则返回包含此 collection 元素的数组。否则,将分配一个具有指定数组的运行时类型和此 collection 大小的新数组。

如果指定的数组能容纳 collection,并有剩余空间(即数组的元素比 collection 的元素多),那么会将数组中紧接 collection 尾部的元素设置为null。(只有 在调用者知道此 collection 没有包含任何 null 元素时才能用此方法确定 collection 的长度。)

如果此 collection 对其迭代器返回的元素顺序做出了某些保证,那么此方法必须以相同的顺序返回这些元素。

toArray() 方法一样,此方法充当基于数组的 API 与基于 collection 的 API 之间的桥梁。更进一步说,此方法允许对输出数组的运行时类型进行精确控制,并且在某些情况下,可以用来节省分配开销。

假定 x 是只包含字符串的一个已知 collection。以下代码用来将 collection 转储到一个新分配的 String 数组:

     String[] y = x.toArray(new String[0]); 
注意, toArray(new Object[0])toArray() 在功能上是相同的。

参数:
a - 存储此 collection 元素的数组(如果其足够大);否则,将为此分配一个具有相同运行时类型的新数组。
返回:
包含此 collection 中所有元素的数组
抛出:
ArrayStoreException - 如果指定数组的运行时类型不是此 collection 每个元素运行时类型的超类型
NullPointerException - 如果指定的数组为 null

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

N3verL4nd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值