zoukankan      html  css  js  c++  java
  • Java Arrays 和 List的相互转化

    最近在 leetcode 刷题的时候遇到过好几次这样的情况:需要返回的数据类型是数组(Arrays),但是求解的时候并不知道数组的长度,这时候就需要先用 List 进行临时存储,最后再转化为 Arrays 返回。所以这里将 java 中 ArraysList 之间的转化总结一下。

    Arrays 转为 List

    1. 利用Arrays.asList() 方法

    Arrays类提供了 asList() 方法,我们先来看看源码:

    可以看到,Arrays.asList() 是泛型方法,传入的必须是对象数组而不是基本数据类型的数组。首先拿 String 数组来看一下:

    没有问题,数组“变成了” List,并且可以通过Listget() 方法进行元素访问。但是换成 int[] 数组呢?

    Eclipse提示出错了,需要将 List 的元素类型换成 int[],也就是说对于基本数据类型的数组,Arrays.asList() 会将整个数组作为一个最后返回的列表中的一个对象。不信的话就改成 int[] 试一下,看结果:

    所以,对于基本数据类型的数组,是不能用 Arrays.asList() 将其转化为 List的。

    另一个坑
    是不是以为对于对象数组,Arrays.asList()就可以无脑使用了呢?还是图样图森破啊。再看看源码:

    发现了吧!Arrays.asList()这里返回的ArrayList并不是java.util.ArrayList,而是java.util.Arrays自己定义的一个静态内部类,这个内部类继承了AbstarctList类。并且,这个自定义的内部类并没有实现java.util.List 的修改方法例如addremove。因此对于转化后的List对象如果进行修改会报异常!!

    2. 使用 Java8Stream接口

    挖完坑之后当然是要填坑了。其实自己实现Arrays 转为 List最简单的就是遍历添加了,不用多说。这里说一个Java8以上版本中的高级操作——Stream接口,这个接口主要就是用来支持对元素流的函数式操作,更详细的介绍可以参考官方文档。先给出转化代码:

    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        List<Integer> ls =  Arrays.stream(arr).boxed().collect(Collectors.toList());
        System.out.println(ls.get(0));
    }
    

    上面代码得到的 ls 支持列表的元素操作函数。Arrays.stream() 函数返回一个IntStream对象(存储原始int类型的Stream),boxed()函数是 IntStream 对象的装箱函数,返回Stream<Integer>对象。collect()函数根据指定的Collector 对流元素进行对应操作,上面代码中 Collectors.toList() 返回一个将所有元素收集到一个 List中的 Collector

    List 转为 Arrays

    1. 使用 List.toArray()方法

    List 有两个toArray()方法,其中无参的toArray()方法返回的是Object[]数组,也无法通过强制类型转换转换成别的类型(所以不明白无参的这个方法应用场景在哪里)。此外还有一个有参的泛型方法 <T> T[] toArray(T[] a),这个方法可以返回指定类型的数组,但是也只能是引用类型:

    List<String> ls = new ArrayList<>();
    ls.add("java");
    ls.add("python");
    ls.add("php");
    String[] arr = ls.toArray(new String[0]);
    System.out.println(arr[1]);
    

    像这样就没问题,但是对于基本数据类型像charint这样就会报错,必须指定为对应的包装类才可以。因此即使是 <T> T[] toArray(T[] a)这个方法,也无法直接将Integer的列表转化为int[]数组。

    2. 使用 Java8Stream接口

    List<Integer>int[]为例,下面这段代码就可以实现转化:

    List<Integer> ls = new ArrayList<>();
    ls.add(1);
    ls.add(3);
    ls.add(4);
    int[] arr = ls.stream().mapToInt(Integer::intValue).toArray();
    System.out.println(arr[1]);
    

    首先通过stream()方法将列表转化为流对象,再通过mapToInt()函数将流对象中的元素映射成int类型,最后通过StreamtoArray方法转化为数组。其中mapToInt() 参数为给定的映射函数,这里表示映射到int类型。::也是java8中的操作符,表示对Integer类的intValue()方法的调用,更多的使用方式可以看官方文档

    总结

    Java集合中只能存放引用类型的数据,不能存放基本数据类型,因此在对基本数据类型数据进行“Arrays-to-List”或者“List-to-Arrays”操作的时候,类本身的方法可能不适用,这时候就必须手动遍历转化,或者利用Java8的Stream接口帮助实现。上面的实现看起来好像是把简单问题变复杂了,确实在进行简单转化的时候遍历复制元素是最方便的,但是Stream接口还有一些强大的功能,如果转化过程中还有一些复杂操作像元素筛选、过滤等 Stream 接口就能够用到了。

  • 相关阅读:
    Amoeba -- 阿里巴巴工程师的开源项目之一陈思儒
    js表达式与语句的区别
    互联网公司github项目汇总
    CDN解决方案
    免费评论组件多说
    ajax同步的实现
    两种时间格式化对比
    Google Gson 使用简介
    使用XStream解析MXL文件用到的jar包---xpp3_min-1.1.3.4.O.jar和xstream-1.3.1.jar
    《Netty in Action》中文版
  • 原文地址:https://www.cnblogs.com/rezero/p/13906929.html
Copyright © 2011-2022 走看看