数组转化为集合
使用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]
集合转化为数组
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异常。
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
-