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

Arrays 转为 List

1. 利用Arrays.asList() 方法

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



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

没有问题,数组“变成了” List,并且可以通过List的 get() 方法进行元素访问。但是换成 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 的修改方法例如add、remove等。因此对于转化后的List对象如果进行修改会报异常!!

2. 使用 Java8 的Stream接口

挖完坑之后当然是要填坑了。其实自己实现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]);

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

2. 使用 Java8 的Stream接口

以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类型,最后通过Stream的 toArray方法转化为数组。其中mapToInt() 参数为给定的映射函数,这里表示映射到int类型。::也是java8中的操作符,表示对Integer类的intValue()方法的调用,更多的使用方式可以看官方文档。

总结

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

Java Arrays 和 List的相互转化的更多相关文章

  1. Java Arrays Tutorial (3)

    Java Arrays Tutorial (3) Data types have a specific set of values. A byte cannot hold a value larger ...

  2. json:JSONObject包的具体使用(JSONObject-lib包是一个beans,collections,maps,java arrays和xml和JSON互相转换的包)

    1.JSONObject介绍 JSONObject-lib包是一个beans,collections,maps,java arrays和xml和JSON互相转换的包. 2.下载jar包 http:// ...

  3. Java Arrays.sort源代码解析

    前提: 当用到scala的sortWith,发现: def sortWith(lt: (A, A) ⇒ Boolean): List[A] // A为列表元素类型 根据指定比较函数lt进行排序,且排序 ...

  4. java Arrays.asList用法

    java Arrays.asList用法 用途 Arrays是java容器相关操作的工具类,asList方法将Array转换为list,是Array和List之间的桥梁. 注意 Arrays.asLi ...

  5. Java Arrays.sort相关用法与重载

    Java Arrays.sort() Java中的数组排序函数, 头文件 import java.util.Arrays; 相关API Arrays.sort(arys[]) Arrays.sort( ...

  6. Top 10 Methods for Java Arrays

    作者:X Wang 出处:http://www.programcreek.com/2013/09/top-10-methods-for-java-arrays/ 转载文章,转载请注明作者和出处 The ...

  7. Java Arrays类进行数组排序

    排序算法,基本的高级语言都有一些提供.C语言有qsort()函数,C++有sort()函数,java语言有Arrays类(不是Array).用这些排序时,都可以写自己的排序规则. Java API对A ...

  8. JAVA Arrays.binarySearch

    转自:http://blog.csdn.net/somebodydie/article/details/8229343 package com.jaky; import java.util.*; pu ...

  9. java Arrays.asList()和Collections.addAll()

    java中的方法Arrays.asList(arg1,arg2,arg3...),经常用在将多个元素或数组转化为List中的元素,但是在使用的时候,应该注意: arg1决定返回list的元素类型(即第 ...

随机推荐

  1. eureka集群的搭建

    本次将会创建三个注册中心和一个客户端进行集群,架构图如下: 修改本机hosts文件,创建三个域名: 代码结构如图: 由于三个注册中心结构都是一样的,区别在于配置文件: #注册中心(eureka-ser ...

  2. RabbitMQ小记(四)

    1.RabbitMQ管理 (1)权限管理 物理服务器和虚拟主机都各自有独立的权限管理,用户访问需要设置权限. 授权命令:rabbitmqctl set permissions [-p vhost] { ...

  3. 关于 K210 MaixPy 的 I2C 读取设备,搜索不到设备,通信失败的一些原因以及解决方案。

    近来对 amigo 开发期间的遇到 I2C 问题做一下总结. 我们发现有一些 I2C 设备搜索不到,主要原因是 DATA 的信号衰减,也可能是 I2C 的总线被拉住了. 软件层面的问题 例如在实现 A ...

  4. Android Studio3.5在编译项目出现连接不上gradle该怎么办?

    ------------恢复内容开始------------ 报错原因: Could not get resource 'https://dl.google.com/dl/android/maven2 ...

  5. TMS, XYZ & WMTS的不同

    WMS是OGC定义的协议,用于请求任意区域的渲染地图图像.客户可以根据需要以平铺模式对其进行请求. WMS-C是OSGeo创建的WMS扩展,它向功能文档中添加了元数据,以使客户端知道在哪里发出请求,从 ...

  6. 基于python实现二叉树的遍历

    """ 二叉树实践: 用递归构建树的遍历 # 思路分析 -- 1.使用链式存储,一个Node表示一个数的节点 -- 2.节点考虑使用两个属性变量,分别表示左连接右连接 & ...

  7. pytest文档58-随机执行测试用例(pytest-random-order)

    前言 通常我们认为每个测试用例都是相互独立的,因此需要保证测试结果不依赖于测试顺序,以不同的顺序运行测试用例,可以得到相同的结果. pytest默认运行用例的顺序是按模块和用例命名的 ASCII 编码 ...

  8. 链接WPA2-企业WIFI时出现无法链接到该网络,可以链接个人WIFI时的问题和解决方案

    因在一个问题上掉两次坑所以还是决定记录下来,方便以后查阅. 第一次因为要部署.net 应用程序要求使用TLS1.2,所以修改了操作系统的默认启用的安全协议类型,导致好多应用程序出问题. 第二次因为vs ...

  9. 第二个 SignalR,可以私聊的聊天室

    一.简介 上一次,我们写了个简单的聊天室,接下来,我们来整一个可以私聊的聊天室. SignalR 官方 API 文档 需求简单分析: 1.私聊功能,那么要记录用户名或用户ID,用于发送消息. 2.怎么 ...

  10. ServletResponse使用介绍

    ServletResponse为将响应发送到客户端的对象:Servlet 容器创建 ServletResponse 对象,并将它作为参数传递给Servlet的service 方法,如下图 : Http ...