目录
1. 泛型方法 + 手动遍历
2. Arrays.asList() + 列表构造器
3. Arrays.stream() + Stream.collect() 方法
4. Guava 的工具类 (推荐)
1. 泛型方法 + 手动遍历
这是一种手动实现的方式, JDK1.5 之后才能实现。其原理就是利用泛型方法,使用循环遍历数组,将其手动转为集合。示例代码如下:
/ * 第一种数组转列表的方式: * JDK1.5+ 泛型方法 + 手动遍历 * * @author wl * @date 2022/10/12 11:21 */ public class ArrayToList01 { public static void main(String[] args) { // 创建一个 Integer 类型的数组 Integer [] arr = {16, 41, 89, 33, 40, 54, 48, 37, 35, 44, 26, 53, 28, 24, 36, 18, 61, 29, 66, 66, }; List<Integer> manual = manual(arr); } / * 利用 JDK1.5 之后的泛型特性, * 手动将数组转为列表 * * @param array 待转为集合的数组 * @return java.util.List<T> * @author wl * @date 2022/10/17 18:17 */ public static <T> List<T> manual(final T[] array) { // 创建一个泛型列表 final List<T> list = new ArrayList<>(array.length); // 遍历数组,手动将其每个元素加入到刚创建的泛型列表中 for (final T i : array) { list.add(i); } // return list; } }
讯享网
不过这个方法仅适用于对象类型的数组,如果是基本数据类型的数组,就比较麻烦,需要为每一种数据类型写一个单独的方法,如下所示:
讯享网/ * 第一种数组转列表的方式: * JDK1.5+ 泛型方法 + 手动遍历 * * @author wl * @date 2022/10/12 11:21 */ public class ArrayToList01 { public static void main(String[] args) { // 创建一个 Integer 类型的数组 int [] arr = {16, 41, 89, 33, 40, 54, 48, 37, 35, 44, 26, 53, 28, 24, 36, 18, 61, 29, 66, 66, }; // 将数组转为对应类型的列表 List<Integer> manual = manual(arr); } / * 将 byte 数组转为 Byte 列表 * * @param array 数组 * @author wl * @date 2022/10/17 19:19 * @return java.util.List<java.lang.Integer> */ public static List<Byte> manual(byte[] array) { // 创建一个泛型列表 final List<Byte> list = new ArrayList<>(array.length); // 遍历数组,手动将其每个元素加入到刚创建的泛型列表中 for (final byte i : array) { list.add(i); } return list; } / * 将 short 数组转为 Short 列表 * * @param array 数组 * @author wl * @date 2022/10/17 19:19 * @return java.util.List<java.lang.Integer> */ public static List<Short> manual(short[] array) { // 创建一个泛型列表 final List<Short> list = new ArrayList<>(array.length); // 遍历数组,手动将其每个元素加入到刚创建的泛型列表中 for (final short i : array) { list.add(i); } return list; } / * 将 int 数组转为 Integer 列表 * * @param array 数组 * @author wl * @date 2022/10/17 19:19 * @return java.util.List<java.lang.Integer> */ public static List<Integer> manual(int[] array) { // 创建一个泛型列表 final List<Integer> list = new ArrayList<>(array.length); // 遍历数组,手动将其每个元素加入到刚创建的泛型列表中 for (final int i : array) { list.add(i); } return list; } / * 将 long 数组转为 Long列表 * * @param array 数组 * @author wl * @date 2022/10/17 19:19 * @return java.util.List<java.lang.Integer> */ public static List<Long> manual(long[] array) { // 创建一个泛型列表 final List<Long> list = new ArrayList<>(array.length); // 遍历数组,手动将其每个元素加入到刚创建的泛型列表中 for (final long i : array) { list.add(i); } return list; } / * 将 boolean 数组转为 Boolean 列表 * * @param array 数组 * @author wl * @date 2022/10/17 19:19 * @return java.util.List<java.lang.Integer> */ public static List<Boolean> manual(boolean[] array) { // 创建一个泛型列表 final List<Boolean> list = new ArrayList<>(array.length); // 遍历数组,手动将其每个元素加入到刚创建的泛型列表中 for (final boolean i : array) { list.add(i); } return list; } / * 将 float 数组转为 Float 列表 * * @param array 数组 * @author wl * @date 2022/10/17 19:19 * @return java.util.List<java.lang.Integer> */ public static List<Float> manual(float[] array) { // 创建一个泛型列表 final List<Float> list = new ArrayList<>(array.length); // 遍历数组,手动将其每个元素加入到刚创建的泛型列表中 for (final float i : array) { list.add(i); } return list; } / * 将 double 数组转为 Double 列表 * * @param array 数组 * @author wl * @date 2022/10/17 19:19 * @return java.util.List<java.lang.Integer> */ public static List<Double> manual(double[] array) { // 创建一个泛型列表 final List<Double> list = new ArrayList<>(array.length); // 遍历数组,手动将其每个元素加入到刚创建的泛型列表中 for (final double i : array) { list.add(i); } return list; } }
由于 JDK 官方的 “ 短视 ” ,在早期,也就是 JDK版本还是 1.0 时候的版本没能推出泛型,直到 JDK 1.5 之后才引入了泛型。因为引入的很晚, JDK 官方也考虑到代码可能会有部分兼容性的问题,如果实现真泛型的话,原先的 JDK1.0 的部分代码可能会无法运行。
/ * 第一种数组转列表的方式: * JDK1.5+ 泛型方法 + 手动遍历 * * @author wl * @date 2022/10/18 9:22 */ public class ArrayToList01 { public static void main(String[] args) { List<Integer> integerList = new ArrayList<>(20); integerList.add(1); List<Double> doubleList = new ArrayList<>(20); doubleList.add(1.0D); Class<? extends Integer> aClass = integerList.get(0).getClass(); Class<? extends Double> aClass1 = doubleList.get(0).getClass(); // 这里会打印出 true System.out.println(aClass.getClass() == aClass1.getClass()); } }
所以为了保持代码的兼容性,在使用泛型的时候,程序在底层执行 javac 命令编译的时候就会将所有的泛型类型直接替换为 Object 的类型。
2. Arrays.asList() + 列表构造器
上面那种是手动转置的写法,一般情况不会用到,正常写代码都会直接使用现成的工具类或方法。这是一种常见的写法,相信大家或多或少都见过,不过还是要在这里介绍一下:
讯享网/ * 第二种数组转列表的方式: * Arrays.asList() + 列表构造器 * * @author wl * @date 2022/10/12 11:21 */ public class ArrayToList02 { public static void main(String[] args) { // 创建数组 Double[] doubles = new Double[10]; Scanner in = new Scanner(System.in); for (int i = 0; i < doubles.length; i++) { doubles[i] = in.nextDouble(); } // 将数组转为对应类型的列表 List<Double> arrayList = new ArrayList<>(Arrays.asList(doubles)); } }
有细心的同学可能会发现 Arrays.asList() 方法其实就可以返回一个列表了,为什么还需要借列表的构造器方法创建列表。其实,原因是这样的,Arrays.asList() 确实会返回一个列表不假,但是这是一个 “ **版 ” 的列表,无法执行增删元素操作,如果强制调用其 add() 或 remove() 方法,就会抛出一个 UnsupportedOperationException 异常,查看底层实现你会发现 Arrays.asList() 方法返回的列表其实是自带的一个内部类,没有实现增删元素的方法所以调用的时候就会报错。
此外,这个方法不适合基本数据类型的数组,必须要先将其转为其包装类的数组才行
3. Arrays.stream() + Stream.collect() 方法
此方法只适用于 JDK1.8 之后的版本,通过 Stream 流的方法间接把数组转为列表,如果你还不知道如何使用 Stream 流,那么可以看看我的另一篇文章:巧用Stream流
好了,废话不多说,看看示例吧:
/ * 第三种数组转列表的方式: * Arrays.stream() + Stream.collect() 方法 * * @author wl * @date 2022/10/12 11:21 */ public class ArrayToList03 { public static void main(String[] args) { // 创建一个 long 基本数据类型的数组 Long[] longs = new Long[20]; for (int i = 0; i < longs.length; i++) { longs[i] = (long) (Math.random() * 100L) + 1L; } // 将数组转为 Stream 流 Stream<Long> stream = Arrays.stream(longs); // 将 Stream 流转为列表 List<Long> arrayList = stream .collect(Collectors.toList()); } }
这种方式也支持部分基本数据类型的数组转为列表,其中包含 int、double 和 long,其他的基本数据类型数组暂不支持:
讯享网/ * 第三种数组转列表的方式: * Arrays.stream() + Stream.collect() 方法 * * @author wl * @date 2022/10/12 11:21 */ public class ArrayToList03 { public static void main(String[] args) { // 创建 double 类型的数组 double[] arr = {1.2, 7.4, -4,8, 9.2, 4.0}; // 通过 Stream 流创建列表 ArrayList<Object> arrayList = Arrays .stream(arr) .collect(ArrayList::new, ArrayList::add, ArrayList::addAll); // 还可以依赖 Boxed 的装箱操作实现 List<Double> arrayList2 = Arrays.stream(arr) .boxed() .collect(Collectors.toList()); } }
4. Guava 第三方库 (推荐)
在使用前需要先引入依赖或 jar 包:
<!-- https://mvnrepository.com/artifact/com.google.guava/guava --> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>23.0</version> </dependency>
这个第三方库的工具非常完善,有很多方法,不过主要有两种类型的的集合,一种为不可变集合,可以使用 ImmutableList 类及其 of()与 copyOf() 的方法来创建:
讯享网/ * 第四种数组转列表的方式: * Guava 的工具类 (推荐) * * @author wl * @date 2022/10/12 11:21 */ public class ArrayToList04 { public static void main(String[] args) { String[] aStringArray = {"string", "elements"}; // 对于可变参数使用 ImmutableList 的 of() 方法进行创建 List<String> i1 = ImmutableList.of("string", "elements"); // 对于数组则可以使用 ImmutableList 的 copyOf() 方法创建 List<String> i2 = ImmutableList.copyOf(aStringArray); } }
为什么要使用不可变集合呢,因为不可变集合主要有以下优点:
- 在多线程操作下,是线程安全的。
- 所有不可变集合会比可变集合更有效的利用资源。
- 当对象被不可信的库调用时,不可变形式是安全的。
- 不可变集合不需要考虑变化,因此可以节省时间和空间。
- 不可变对象因为有固定不变,可以作为常量来安全使用。
另一种为可变集合,不过在可变集合上,似乎 Guava 不支持用数组创建,因为可变集合的大部分类都是 Map、Set 之类,无法直接或间接支持使用数组进行创建列表,如果想使用可变集合,那么使用 JDK 的 ArrayList 或 LinkedList 就行。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/125039.html