当前位置:首页 > 技术文章 > 正文内容

面试官-如何实现数组和 List 之间的转换?

zonemu3个月前 (07-10)技术文章46

数组和List是Java开发中常见的两种数据结构,那么如何实现二者之间的快速转换就成了面试官常问的考点之一,下面我们我们就来从数组转List和List转数组两个方面来展开介绍一下。

数组转List

方法一、通过Arrays.asList()

这个方法生成的List是一个固定大小的List,也就是说它的长度不能被修改,即不能添加元素也不能修改元素,因为修改返回的List可能会直接影响到原数组的数据,这里涉及到的知识点叫做引用共享。所谓的引用共享是指当多个变量引用同一个对象的时候,实际上它们共享的是同一个内存地址,因此通过任意一个变量修改对象的内容那么其他的变量也会同步感知到这些修改。因为在Java中除了基本数据类型除外的其他对象都是通过引用来操作的,而非直接操作对象本身,而这种机制就导致了引用共享的现象,有兴趣的读者可以深入进行研究,这里不做过多的介绍。

具体实现如下所示。

String[] array = {"A", "B", "C"};
List<String> list = Arrays.asList(array);

当然如果要返回一个可变的List,我们可以通过如下的方式来实现。

List<String> modifiableList = new ArrayList<>(Arrays.asList(array));

方法二、使用 Collections.addAll()

这种方式创建的List对象是一个可变的对象,可以自由对List进行增删改查,这种实现方式比较灵活,适合需要对结果列表进行进一步操作的场景,如下所示。

String[] array = {"A", "B", "C"};
List<String> list = new ArrayList<>();
Collections.addAll(list, array);

方法三、使用流 (Stream)

在Java8开始提供了Stream的API,所以我们可以通过流式编程的方式来将数组元素转换成List,然后对其进行进一步的操作,如下所示。

String[] array = {"A", "B", "C"};
List<String> list = Arrays.stream(array).collect(Collectors.toList());

当然还有以其他的方式可以实现数组到List的转换,有兴趣的读者可以深入的了解一下,介绍上面的几种实现方式,有一个核心的考点就是引用共享,可能在面试过程中当你提到这个概念的时候,面试官会继续追问什么是引用共享,这里由于篇幅有限,我们先不深入展开介绍,在后续的分享中,我们来详细介绍一下什么引用共享。

介绍完数组转List下面我们就来介绍一下List转数组。

List 转数组

相比数组转List,List转数组会相对来说简单一些,如下所示。

方法一、使用 toArray()

我们可以通过List提供的toArray(T[] a)方法来进行转换,可以看到需要传入一个数组参数对象,如下所示。

List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");

String[] array = list.toArray(new String[0]); // 推荐用法

我们传入的是一个大小为0的参数,那么当参数长度为0的时候,toArray 会动态分配合适大小的新数组,那么如果这个数组涉及的长度较大的时候,我们就可以直接使用传入的数组,这里涉及到的知识点也是引用共享。

方法二、使用流 (Stream)

在Java8以后,我们还可以通过Stream流的方式来实现List转数组,如下所示。

List<String> list = Arrays.asList("A", "B", "C");
String[] array = list.stream().toArray(String[]::new);

通过这种方式,我们可以在完成了过滤、映射等操作之后,在进行数组的转换。

细节和面试回答建议

在面试过程中,除了上面介绍上的方式之外,可能还需要注意如下的一些细节。

第一、性能

选择何种转换方式,主要取决于需求,但也要考虑性能,例如Arrays.asList() 的性能很高,但生成的 List 是不可变长度的,适合小范围的快速转换。Collections.addAll()Stream 方法更灵活,但需要额外的空间分配。

第二、线程安全性

在进行数据结构转换的过程中,如果涉及到多线程的操作,那么就需要考虑到线程安全的问题,例如,可以使用 Collections.synchronizedList() 来包装可变 List,使其达到线程安全的目的。

第三、边界值处理

可能有些面试官会问到,如果数组为空的情况下转换之后的结果是什么?又或者会问到如何处理Null,也就是说如何避免转换结束使用的时候出现 NullPointerException

第四、需求论

上面提到解决什么样的问题,选择什么样的方式,避免因为错误选择导致系统性能问题。

总结

在上面的介绍中,有一个问题没有回答就是引用共享的问题,在下一篇博客中我们详细来介绍一下什么是引用共享,希望大家多多的关注,敬请期待。

相关文章

Garuda Linux:现代化、注重性能与美观的Linux发行版

什么是 Garuda Linux?Garuda Linux 是一个基于 Arch Linux 的现代化、注重性能与美观的桌面操作系统。它面向对性能有较高要求的用户,尤其受到 Linux 爱好者、游戏玩...

Vue3 如何实现父子组件传值?(vue父子组件传值props)

在Vue 3中,要实现父子组件传值效果主要通过props和emit两种机制来实现,下面我们就来详细介绍一下这两种机制。父组件向子组件传值propsprops是Vue组件的一种机制,主要的作用就是实现从...

快速上手React(快速上手的高级表达)

web前端三大主流框架1、Angular大家眼里比较牛的框架,甚至有人说三大框架中只有它能称得上一个完整的框架,因为它包含的东西比较完善,包含模板,数据双向绑定,路由,模块化,服务,过滤器,依赖注入等...

Vue基础(vue基础组件文件名符合规范的是)

Vue 是什么,它的核心特点有哪些?Vue 是一款渐进式 JavaScript 框架,它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助开发者用...

web前端入门:css+html5+javascript同时学可以吗?

HTML+CSS+JS是前端基础核心知识,肯定是都要学的。在web前端中,HTML是结构标准,CSS是样式标准,JS是行为标准,三者缺一不可。说的直白点,HTML就是骨架,CSS就是皮肤,JS就是灵魂...

HTML5最新版本介绍(“html5”)

HTML5是HTML4.01和XHTML1.0之后超文本标记语言的最新版本,由一群自由思想者设计,最终实现了多媒体支持、交互性、更智能的表单和更好的语义标注。 HTML 5不只是 HTML规范的最新...