Java中ArrayList和SubList的坑面试题

 更新时间:2022年05月26日 10:28:38   作者:芝士味的椒盐  
集合是Java开发日常开发中经常会使用到的,下面这篇文章主要给大家介绍了关于Java中ArrayList和SubList的坑面试题,需要的朋友可以参考下

代码复现

不要,思考一下会打印出什么?

        List<String> list1 = new ArrayList<>(Arrays.asList("username", "passwd"));
        List<String> list2 = list1.subList(0, 2);
        list2.add("email");
        System.out.println(list1);
        System.out.println(list2);

执行结果:

你是否感觉疑惑?在想为什么在list2添加的在list1也添加是吧?

源码解析

subList接口

List<E> subList(int fromIndex, int toIndex);

我们使用的是ArrayList,所以是选择ArrayList即可

    public List<E> subList(int fromIndex, int toIndex) {
    subListRangeCheck(fromIndex, toIndex, size);
    return new SubList(this, 0, fromIndex, toIndex);
}

fromIndex是从List元素开始索引,toIndex是List元素结束索引,subListRangeCheck方法是检查是否在允许范围之内。

    static void subListRangeCheck(int fromIndex, int toIndex, int size) {
    	//开始索引小于0
        if (fromIndex < 0)
            throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
            //结束索引大于容量
        if (toIndex > size)
            throw new IndexOutOfBoundsException("toIndex = " + toIndex);
            //开始索引大于结束索引
        if (fromIndex > toIndex)
            throw new IllegalArgumentException("fromIndex(" + fromIndex +
                                               ") > toIndex(" + toIndex + ")");

重头戏在new SubList(this, 0, fromIndex, toIndex);这里,看看下面的SubList就会知道,this关键字将当前对象的引用也就是list1传入了SubList,把传入的list1变成parent赋值给SubList内部成员,然后又将这个构造生成的赋值给list2,也就是说list1和list2是引用了同一个对象,指向的是同一list。

        SubList(AbstractList<E> parent,
                int offset, int fromIndex, int toIndex) {
             //问题就出现在这里
            this.parent = parent;
            this.parentOffset = fromIndex;
            this.offset = offset + fromIndex;
            this.size = toIndex - fromIndex;
            this.modCount = ArrayList.this.modCount;
        }

再来看看list2.add的源码,将元素直接添加在list1和list2共同的list引用对象上,这就是为什么list2添加了,list1也添加了。

        public void add(int index, E e) {
            rangeCheckForAdd(index);
            checkForComodification();
            //将元素直接添加在list1和list2共同的list引用对象上
            parent.add(parentOffset + index, e);
            this.modCount = parent.modCount;
            this.size++;
        }

附:ArrayList的subList简单介绍和使用

subList(int fromIndex, int toIndex);

它返回原来list的从[fromIndex, toIndex)之间这一部分其实就是list的子列表(注意:fromIndex是 [ 说明包括其本身,toIndex是 )说明不包括其本身)。

这个子列表的本质其实还是原列表的一部分;也就是说,修改这个子列表,将导致原列表也发生改变。

举例说明

list中包含1,2,3,4,5,6一共6个元素,list.subList(1,3)返回的是2,3(list以0为开始)

还有一个经常使用的list.subList(1,list.size)

list中包含1,2,3,4,5,6一共6个元素,list.subList(1,list.size)返回的是2,3,4,5,6(list以0为开始)

总结

到此这篇关于Java中ArrayList和SubList的坑面试题的文章就介绍到这了,更多相关ArrayList和SubList面试题内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot如何自定义starter

    SpringBoot如何自定义starter

    这篇文章主要介绍了SpringBoot如何自定义starter,Springboot的出现极大的简化了开发人员的配置,而这之中的一大利器便是springboot的starter,starter是springboot的核心组成部分,下面来看看集体引用过程吧
    2022-01-01
  • 如何在springboot中配置和使用mybatis-plus

    如何在springboot中配置和使用mybatis-plus

    这篇文章主要给大家介绍了关于如何在springboot中配置和使用mybatis-plus的相关资料,MyBatis Plus是MyBatis的增强版,旨在提供更多便捷的特性,减少开发工作,同时保留了MyBatis的灵活性和强大性能,需要的朋友可以参考下
    2023-11-11
  • Kotlin基础教程之函数定义与变量声明

    Kotlin基础教程之函数定义与变量声明

    这篇文章主要介绍了Kotlin基础教程之函数定义与变量声明的相关资料,需要的朋友可以参考下
    2017-05-05
  • java计算两个日期之间相差天数的4种方法详解

    java计算两个日期之间相差天数的4种方法详解

    这篇文章主要给大家介绍了关于java计算两个日期之间相差天数的4种方法,本文简短地介绍java中多种方式求两个日期的差量,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-09-09
  • 深入解析Spring中的@Bean注解

    深入解析Spring中的@Bean注解

    这篇文章主要介绍了深入解析Spring中的@Bean注解,Spring的@Bean注解用于告诉方法,产生一个Bean对象,然后这个Bean对象交给Spring管理,产生这个Bean对象的方法Spring只会调用一次,随后这个Spring将会将这个Bean对象放在自己的IOC容器中,需要的朋友可以参考下
    2023-07-07
  • Java如何实现双向链表功能

    Java如何实现双向链表功能

    双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表
    2021-11-11
  • Java编写实现九宫格应用

    Java编写实现九宫格应用

    这篇文章主要为大家详细介绍了Java编写实现九宫格应用,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • Java实现常用加密算法——单向加密算法MD5和SHA

    Java实现常用加密算法——单向加密算法MD5和SHA

    本篇文章主要介绍了Java实现常用加密算法——单向加密算法MD5和SHA,信息加密后数据更安全,需要的朋友可以参考下。
    2016-10-10
  • Java实现递归读取文件夹下的所有文件

    Java实现递归读取文件夹下的所有文件

    这篇文章主要为大家详细介绍了如何利用Java实现递归读取文件夹下的所有文件,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-02-02
  • Servlet生命周期与工作原理详解

    Servlet生命周期与工作原理详解

    这篇文章主要为大家详细介绍了Servlet生命周期与工作原理的相关资料,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-04-04

最新评论