泛型数组List和数组转换常见方法归纳 + 流方法解析

本文为归纳总结,不会具体说明用法或案例,但会附上相关链接
此外,迭代可以完成任意操作,但没什么好讲的。
所以解决方法并没有写迭代

分两类:
泛型数组(List为例)和

  1. 引用类型数组转换
  2. 基本类型数组转换

前置知识:泛型必须是引用类型,不能是基本类型

方法大总结

  1. List 转 引用类型 : toArray(指定参数)

    List<int[]> list = new LinkedList<>();
    int[][] ans  = list.toArray  (new int[list.size()][]);
    
  2. 引用类型 转 List : Collections.addAll(des, src) (Arrays.asList 不好用)

    String[] strArray = { "array-a", "array-b" };
    List<String> strList = new ArrayList<>();
    Collections.addAll(strList, strArray);
    
  3. 基本类型 转 List / 包装

    int[] intArray = {1, 2, 3, 4};
    List<Integer> list = new ArrayList<>();
    list = Arrays.stream(intArray)
                 .boxed()
        		.collect(Collectors.toList());
    // 最后的collect换成: 
    //.toArray(Integer[]::new)  转为Integer[]
    
  4. List / 包装 转 基本类型

    List<Integer> list = new ArrayList<>();
    //原数组为包装Integer[] integers 第一行换为 : Arrays.stream(integers) 
    int[] intArray = list.stream()
       				    .mapToInt(Integer::valueOf)
        				.toArray();
    

正文:

引用类型数组转换

泛型数组 to 引用类型数组

先说明,引用类型数组中,包括了String[]以及int[] ,String自然不用说,但需注意int[] 也是引用,而这就说明二维数组适用于本范围

toArray(指定类型)

两种形式:

Object[] toArray();
<T> T[] toArray(T[] a);
  1. Object[] toArray() :

    • 用Objcet[] 接收,一般无意义
    • 若强转,编译期不报错,但运行期会报错,因为Object[]不能向下强转

2. T[] toArray(T[] a) : 有效

  • 参数为T,只支持泛型

  • 该方法可以完成包装类型数组的转换:eg: List< Integer > 转 Integer[]

  • 用法eg: 二维数组!!

    List<int[]> list = new LinkedList<>();
    int[][] ans  = list.toArray  (new int[list.size()][]);
    

引用类型数组 to 泛型数组

常用两种:Arrays.asList()、Collections.addAll()(推荐)

  1. Arrays.asList() (细分是两种)

    public static <T> List<T> asList(T... a) {//省略代码}
    

    同上,也要求泛型

    用法eg:

    String[] strArray = { "array-a", "array-b" };
    List<String> strList = Arrays.asList(strArray);
    

    存在问题:

    • 返回值是java.util.Arrays类中一个私有静态内部类java.util.Arrays.ArrayList,
      它并非java.util.ArrayList类
    • 操作有限制,无法add()、remove()

    改进解决:(第二种)

    新建一个List对象,以返回的strList作为参数

    //此时才是java.util.ArrayList
    List<String> strListNew = new ArrayList<>(strList);
    
  2. Collections.addAll() (上面还要两次操作,有、烦,而且本方法效率也比较高,所以推荐)

public static <T> boolean addAll(Collection<? super T> c, T... elements) {
  //代码省略
}

同,也是泛型T参数

用法eg:

String[] strArray = { "array-a", "array-b" };
List<String> strList = new ArrayList<>();
//参数简述:(des,src)
Collections.addAll(strList, strArray);

具体资料:

List与数组互转

Arrays.asList详解


基本类型数组转换

常用三种思路:

  1. 迭代,不解释,循环赋值就完事了
  2. 基本类型数组先循环赋值,转为包装类数组,就适用于上文的引用类型了。(那我为什么不直接循环赋值?无特殊情况不推荐使用) (也有对应流的方法,但也一样道理,为什么不直接一遍流呢?)
  3. stream 流 ,jdk1.8的特性 ,下文只说明流的用法

数据eg:int[] 转为 List< Integer >

int[] intArray ;
List<Integer> list;

泛型数组 to 基本类型数组

List<Integer> list = new ArrayList<>();
int[] intArray = list.stream()
   				    .mapToInt(Integer::valueOf)
    				.toArray();

基本类型数组 to 泛型数组

int[] intArray = {1, 2, 3, 4};
List<Integer> list = new ArrayList<>();
list = Arrays.stream(intArray)
             .boxed()
    		.collect(Collectors.toList());

拓展:基本类型数组和包装类型数组的转换

基本类型数组 to 包装类型数组

  1. 利用泛型数组的toArray方法。所以用上文的方法,先转为泛型,再转为包装类型

    int[] intArray = {1, 2, 3, 4};
    List<Integer> list  = Arrays.stream(intArray)
                 			   .boxed()
        					  .collect(Collectors.toList());
    //↑ 跟上文完全相同 ; ↓ ,借助toArray方法
     Integer[] integers = list.toArray(new Integer[list.size()]);
    
  2. 一步到位:

    int[] intArray = {1, 2, 3, 4};
    Integer[] integers1 = Arrays.stream(intArray)
        					  .boxed()
                                .toArray(Integer[]::new);
    //区别就是最后一个调用的方法:  .collect  ->  .toArray
    

包装类型数组 to 基本类型数组

  1. 一样道理,逆着来,先把包装类型数组转为泛型类型数组 , 再转为基本类型数组

    Integer[] integers = {1,2,3};
    List<Integer> list = new ArrayList<>();
    Collections.addAll(list,integers);   //上文也说了,推荐使用这个
    
    int[] intArray = list.stream()
                    	.mapToInt(Integer::valueOf)
                    	.toArray();
    
  2. 一步到位

    Integer[] integers = {1,2,3};
    //这里的区别是第一行;  ↑ trueList.stream() ->  ↓ Arrays.stream
    int[] intArray = Arrays.stream(integers)
                           .mapToInt(Integer::valueOf)
                           .toArray();
    

相关资料:

ArrayList和数组int[]的相互转化


流的用法总结:

(笔者是觉得死记不容易,理解记忆比较好)

  1. 基本类型数组转换为别的数组

    eg : int[] intArray;
    第一步: Arrays.stream(intArray)

    • 不难理解,毕竟是自己转出去,自己作为流的源
    • stream()会根据参数类型,返回对应类型的流,此处返回IntStream

    第二步: .box() :如方法名,作用是装箱。返回一个Stream< Integer > ,因为第一步获得的是基本类型的流,装箱变为包装类型,才能执行后续方法。

    第三步: 分支点

    • 目标是泛型数组: .collect(Collectors.toList()) ,作用就是从第二步的Stream< Integer > 流中收集元素,并转为对应的List。
    • 目标是包装类型: .toArray(Integer[]::new) ,直接转为数组,参数指定类型
  2. 别的数组转换为基本类型:

    eg:

    Integer[] integers; 
    List<Integer> list
    

    第一步:分支点

    • 源数组为泛型数组:实例变量.stream(),此处就是 list.stream() ,获取到一个Stream< Integer > , 类型是靠实例变量确定的
    • 源数组为包装数组: Arrays.stream(integers) ,该方法已经介绍过了,获得 Stream< Integer > (int[]是IntStream)
    • 两者操作结果一致,都获得了 Stream< Integer >

    第二步:.mapToInt(Integer::valueOf) , 这步其实是拆箱,返回 IntStream

    第三步: .toArray() 转为数组,结束

拓展:可能看到这里,有的读者已经发现了。核心就是 Stream< Integer > ,装箱、拆箱无法在数组层面完成,所以转为流来进行装、拆箱。

甚者:既然 1.基本类型数组转换为别的数组 中,也是获得了Stream< Integer > ,通过操作这个流,就能转换为泛型数组(当然,包装数组也可以)

那 Integer[] 也能获得 Stream< Integer > , 那是不是也可以通过一样的操作,获得对应的泛型数组呢。 答案是:没错

Integer[] integers = {1,2,3};
List<Integer> list = Arrays.stream(integers)
                    .collect(Collectors.toList());

当然了,不是说 Arrays.asList()、Collections.addAll() 不香,只是拓展一下各位的思路。


本文完,有误欢迎指出

©️2020 CSDN 皮肤主题: 技术工厂 设计师:CSDN官方博客 返回首页