子列表只是原列表的一个视图

原文参考:《编写高质量代码:改善java程序的151个建议》

本文原创:穆雄雄

上期文章:

subList?? subString???

上期我们说到,List接口提供了subList方法,其作用是返回一个列表的子列表。并且我们通过案例说明了一个问题,那便是,在原来的list集合基础上,调用subList产生新的List的时候,那么原来的list集合也会随之而改。

在看为什么之前,我们还是先从subList的源码上说起吧。

public List<E> subList(int fromIndex, int toIndex) {

  return (this instanceof RandomAccess ?

  new RandomAccessSubList<E>(this, fromIndex, toIndex) :

  new SubList<E>(this, fromIndex, toIndex));

}

从代码中我们可以看到,instanceof的作用就是查看当前的对象是否是RandomAccess的实例,如果是,则调用RandomAccessSubList方法,否则调用SubList方法,况且进一步查看源码可以得知RandomAccessSubList类也继承至SubList类,所以我们直接来看SubList的源码:

class SubList<E> extends AbstractList<E> {

  private final AbstractList<E> l;

  private final int offset;

  private int size;



  SubList(AbstractList<E> list, int fromIndex, int toIndex) {

    if (fromIndex < 0)

    throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);

    if (toIndex > list.size())

    throw new IndexOutOfBoundsException("toIndex = " + toIndex);

    if (fromIndex > toIndex)

    throw new IllegalArgumentException("fromIndex(" + fromIndex +

    ") > toIndex(" + toIndex + ")");

    l = list;

    offset = fromIndex;

    size = toIndex - fromIndex;

    this.modCount = l.modCount;

  }

}
//后面省略其他方法

通过阅读这段代码,我们就很清楚的知道SubList方法的实现原理,它返回的SubList类也是AbstractList的子类,其所有的方法如get、set、add、remove等都是在原始列表上的操作,它自身并没有生成一个数组或是链表,也就是子列表只是原列表的一个视图(View),所有的修改动作都反映在了原列表上。

所以我们表面上操作的是newList,其实操作的还是原来的列表。subList产生的列表只是一个视图,所有的修改动作直接作用于源列表。

往期精彩

“半路出家”的程序猿怎么不被“熊”

2020-10-11

某同学工作之后的感悟

2020-10-10

班级日常分享,一天一瞬间

2020-10-10

为了金秋那沉甸甸的麦穗,我绝不辜负春天

2020-10-09

subList?? subString???

2020-10-08

"爸妈没多大本事"……

2020-10-07

点分享

点点赞

点在看

posted @ 2020-10-12 06:00  穆雄雄  阅读(38)  评论(0编辑  收藏  举报