写点什么

ArrayList 和 SubList 的坑面试题

  • 2022 年 4 月 24 日
  • 本文字数:1362 字

    阅读完需:约 4 分钟


👨🏻‍🎓博主介绍:大家好,我是芝士味的椒盐,一名在校大学生,热爱分享知识,很高兴在这里认识大家🌟🌈擅长领域:Java、消息中间件、大数据、运维。

🙏🏻如果本文章各位小伙伴们有帮助的话,🍭关注+👍🏻点赞+🗣评论+📦收藏。

🤝另本人水平有限,旨在创作简单易懂的文章,在文章描述时如有错,恳请各位大佬指正,在此感谢!!!


代码复现

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

        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++;          }
复制代码


发布于: 刚刚阅读数: 2
用户头像

Java、消息中间件、大数据、运维 2022.04.23 加入

华为云云享专家、51CTOtop红人、CSDN博主、2021年第十届“中国软件杯”大学生软件设计大赛-B3-高并发条件下消息队列的设计与实现国赛二等奖、2021年浙江省职业院校技能大赛高职组“大数据技术与应用”赛项一等奖

评论

发布
暂无评论
ArrayList和SubList的坑面试题_Java_芝士味的椒盐_InfoQ写作社区