首页 > 其他分享 >最详细!如何实现数组和List之间的转换?(含详细代码解析,面试题拓展)

最详细!如何实现数组和List之间的转换?(含详细代码解析,面试题拓展)

时间:2024-10-15 11:53:31浏览次数:3  
标签:toArray 面试题 详细 list List 数组 array asList

        数组和List都是我们平时工作,或者主动学习中经常使用的数据结构,在项目中难免会出现需要将其相互转换的场景,同时也正因为此,面试也偶尔会被问到。本文将从其调用的方法,以及其原理、特点展开,希望能让各位读者有所收获,码海无涯,愿与大家共勉。

1,数组转换为List

1,使用Arrays.asList()方法  

   例如,我们需要将一个含有{"A", "B", "C"}的数组转为List集合。可以直接调用java提供的一个简单方法Arrays.asList()。

public class ArrayToListExample {  

    public static void main(String[] args) {  

        String[] array = {"A", "B", "C"};  

        List<String> list = Arrays.asList(array);  

  

        System.out.println(list);  

    }  

}

        但是!值得注意的是,这个列表是固定的,无法进行添加、删除等操作,但是可以进行修改操作。我们都知道List是可以进行扩容的,关于这方面上期文章已经做了详实的解析,有兴趣的读者可以再去看看上一期文章,友情链接:ArrayList源码逐句解析 。那为什么我们已经将其转成了List,还是无法扩容呢?

         关键点就在于asList方法,我们可以看看它的源码。

 public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }

   我们可以很清楚的看到,asList方法调用了Arraylist<>(a),各位读者注意,这个Arraylist<>实际上是我们调用的Arrays当中的一个内部类,不是我们熟知的Arraylist集合,而Arraylist<>(a)是这个内部类中的一个构造方法,同样我们来看看它的源码。

 private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable
    {
        private static final long serialVersionUID = -2764017481108945198L;
        private final E[] a;

        ArrayList(E[] array) {
            a = Objects.requireNonNull(array);
            //对象引用,并未创建新的对象
        }

   到这里我们就清楚了, 它只是执行了一个a = Objects.requireNonNull(array),这个语句只是将a与数组指向同一个地址,并没有新建一个对象,底层还是一个数组。
        那么有没有解决办法呢?当然有。我们可以使用ArrayList构造函数。

2,使用ArrayList构造函数

   同样,我们需要将一个含有{"A", "B", "C"}的数组转为List集合。

public class ArrayToListExample {  

    public static void main(String[] args) {  

        String[] array = {"A", "B", "C"};  

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

  

        list.add("D"); // 可以添加元素  

        System.out.println(list);  

    } 

         与直接使用asList方法相比,我们可以再调用一次Arraylist的构造函数,这样就创建出了一个新Arraylist对象,(关于Arraylist的构造函数的原理,友情链接:ArrayList源码分析)而不是简单的引用,并且我们可以看到,我们再往其中添加元素"D"也是可行的。

        数组转换为List就分析完毕了,接下来我们来看看,List如何转换为数组?

2,List转换为数组

1,使用toArray方法

        与数组转换为List相似,Java的List接口提供了一个toArray()方法,可以将list转换为数组。同样我们以包含{"A", "B", "C"}的集合为例。

public class ListToArrayExample {  

    public static void main(String[] args) {  

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

        String[] array = list.toArray(new String[0]); // 推荐使用这种方式,避免自动装箱  

  

        System.out.println(Arrays.toString(array));  

    }  

}

        其中Arrays.tostring方法是遍历数组并输出的一个方法,读者不必在意,重list.toArray()方法,这是实现list转换为数组的核心方法,我们看看其源码。

 public <T> T[] toArray(T[] a) {
        if (a.length < size)
            return (T[]) Arrays.copyOf(elementData, size, a.getClass());
        System.arraycopy(elementData, 0, a, 0, size);
        if (a.length > size)
            a[size] = null;
        return a;
    }

        我们看其核心代码,System.arraycopy(elementData, 0, a, 0, size),这句代码的意思就是将elementData的数据拷贝到了a中,了解过ArrayLIst底层的读者很清楚elementData就是存储ArrayList元素的数组缓冲区,所以这句代码就是,重新拷贝了一份数据到新的数组中,并返回,所以这里是返回了一个新的对象。

        如果你知道数组的类型和大小,也可以预先分配一个数组,然后传递给toArray()方法。

2,使用toArray(T[] a)

   其逻辑与上述逻辑非常类似,读者可以简单看看源码。

public class ListToArrayExample {  

    public static void main(String[] args) {  

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

        String[] array = new String[list.size()];  

        array = list.toArray(array);  

  

        System.out.println(Arrays.toString(array));  

    }  

}

        可以看到我们预先分配一个Array数组,并以List的大小作为其长度。调用toArray方法,将集合的数据拷贝到该数组。

3,面试题

        接下来我们看看一些面试题,读者如果将上面的方法的代码都仔细跟踪阅读过,对于以下面试题就非常轻车熟路了。

         面试题1:如何实现数组和List之间的转换?

        参考答案: 数组转List,使用JDK中Arrays工具类中的asList方法。 List转数组,使用List中的toArray方法,调用无参方法返回Object数组,传入初始长度的数组对象,返回该数组对象。

        面试题2:使用了asList转List后,如果修改了原来数组的内容,List受影响吗?

        参考答案:使用asList转List后,如果修改了数组的内容,List会受到影响,因为底层使用的Arrays中的一个内部类arrayList来构造的集合,在调用这个构造方法时,只是将我们传入的这个集合做了包装而已,底层依然指向同一个内存地址。

        面试题3:使用了toArray转数组后,如果修改了List内容,数组受影响吗?

        参考答案:List调用了toArray转为数组后,如果修改了List内容,数组不会被影响,调用了toArray后,底层进行了数据的拷贝,返回了新的对象,和原来的数据无关,即使修改了原来的数据,数组也不受影响。

标签:toArray,面试题,详细,list,List,数组,array,asList
From: https://blog.csdn.net/weixin_52469927/article/details/142936336

相关文章

  • 2024软著申请详细流程分享
    软著申请全攻略:轻松掌握网上办理流程软著申请具有诸多优势,相较于专利申请更为简便,申请周期较短,且无需每年缴纳年费,对于计算机领域从业者和程序员而言是极为合适的选择。当前,软著申请既可以自行办理登记,也能够委托专业代理机构进行办理登记。其大体流程涵盖以下步骤:账号注......
  • ReorderableList
    目录简介常用委托事件代码示例简介列表重写的数据类,一般使用在Editor下常用委托事件委托名作用drawElementCallback用于绘制list里的每个elementdrawHeaderCallback用于绘制headerelementHeightCallback用于设置每个element的高度onAddCallbackelemen......
  • PyCharm安装激活汉化(详细教程)
    一、Pycharm的下载与安装1、首先来到Pycharm官网,Pycharm有两个版本,小编这里已经帮大家准备好了安装包,获取方式......
  • 网络安全自学入门:(超详细)从入门到精通学习路线&规划,学完即可就业_网络安全自学路线
    很多人上来就说想学习黑客,但是连方向都没搞清楚就开始学习,最终也只是会无疾而终!黑客是一个大的概念,里面包含了许多方向,不同的方向需要学习的内容也不一样。算上从学校开始学习,已经在网安这条路上走了10年了,无论是以前在学校做安全研究,还是毕业后在百度、360从事内核安全产......
  • 网络安全最厉害五个专业(非常详细),零基础入门到精通,看这一篇就够了
    文章目录1.网安方向介绍01、密码学与应用安全02、量子信息安全03、数据安全04、系统安全05、网络安全2.就业前景分析01、大厂安全部门02、安全公司03、高校==零基础入门黑客技术/网络安全==【----帮助网安学习,以下所有学习资料文末免费领取!----】大纲学习教程面试刷......
  • 大语言模型对普通人最实在的帮助(非常详细),零基础入门到精通,看这一篇就够了
    前言记得小时候流行过一类叫《十万个为什么》的书,听名字就知道这些书好像就是一个巨大无比的知识仓库,里面存放着无穷无尽的知识,可以满足孩子们的一切好奇心——但我小时候从没买过,可能没有什么求知欲吧。现在的孩子,似乎更没有必要买入一本《十万个为什么》了,并不是因为没......
  • 软件著作权申请教程(超详细)(2024新版)软著申请
                目录一、注册账号与实名登记二、材料准备三、申请步骤1.办理身份2.软件申请信息3.软件开发信息4.软件功能与特点5.填报完成一、注册账号与实名登记    首先我们需要在官网里面注册一个账号,并且完成实名认证,一般是注册【个人】的身......
  • 【愚公系列】《AIGC辅助软件开发》042-AI辅助提升程序员求职、招聘与面试效率:用 ChatG
    标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。近期荣誉2022年度博客之星TOP2,2023年度......
  • 【愚公系列】《AIGC辅助软件开发》043-AI辅助提升程序员求职、招聘与面试效率:用ChatGP
    标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。近期荣誉2022年度博客之星TOP2,2023年度......
  • ArrayList源码分析(底层数据结构,成员变量,构造方法)以及面试题(基于JDK1.8)
    要分析Arraylist,我们首先要从它的底层数据结构实现出发,再结合其底层源码,可能能让读者理解的更加深刻一点。1,底层数据结构(数组)Arraylist底层是基于动态数组实现的。数组是一种使用连续储存空间储存相同数据类型的线性数据结构。面试题1为什么数组索引从0开始不从1开始?分......