ArrayList和SubList的坑面试题

举报
芝士味的椒盐 发表于 2022/04/19 13:07:37 2022/04/19
【摘要】 👨🏻‍🎓博主介绍:大家好,我是芝士味的椒盐,一名在校大学生,热爱分享知识,很高兴在这里认识大家🌟🌈擅长领域:Java、大数据、运维、电子🙏🏻如果本文章各位小伙伴们有帮助的话,🍭关注+👍🏻点赞+🗣评论+📦收藏,相应的有空了我也会回访,互助!!!🤝另本人水平有限,旨在创作简单易懂的文章,在文章描述时如有错,恳请各位大佬指正,在此感谢!!!@[TOC] 代码复现不要,思考...

在这里插入图片描述

👨🏻‍🎓博主介绍:大家好,我是芝士味的椒盐,一名在校大学生,热爱分享知识,很高兴在这里认识大家🌟
🌈擅长领域:Java、大数据、运维、电子
🙏🏻如果本文章各位小伙伴们有帮助的话,🍭关注+👍🏻点赞+🗣评论+📦收藏,相应的有空了我也会回访,互助!!!
🤝另本人水平有限,旨在创作简单易懂的文章,在文章描述时如有错,恳请各位大佬指正,在此感谢!!!


@[TOC]

代码复现

  • 不要,思考一下会打印出什么?
        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++;
            }
    
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。