👨🏻🎓博主介绍:大家好,我是芝士味的椒盐,一名在校大学生,热爱分享知识,很高兴在这里认识大家🌟
🌈擅长领域: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) {//开始索引小于0if (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 + ")");
- fromIndex是从List元素开始索引,toIndex是List元素结束索引,subListRangeCheck方法是检查是否在允许范围之内。
-
重头戏在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++;}