有谁知道,为什么AbstractList(以及ArrayList)中的removeRange方法是protected
?它看起来像是一个定义明确且有用的操作,但是要使用它,我们仍然不得不对List实现进行子类化。
有一些隐藏的理由吗?对我来说似乎莫名其妙。
有谁知道,为什么AbstractList(以及ArrayList)中的removeRange方法是protected
?它看起来像是一个定义明确且有用的操作,但是要使用它,我们仍然不得不对List实现进行子类化。
有一些隐藏的理由吗?对我来说似乎莫名其妙。
Answers:
是的,因为这不是您从外部代码中删除范围的方式。相反,请执行以下操作:
list.subList(start, end).clear();
这实际上removeRange
是在幕后。†
OP询问为什么removeRange
不属于List
公共API。原因在《有效Java第二版》的第40条中进行了描述,在此引用:
有三种缩短简短参数列表的技术。一种是将方法分解为多种方法,每种方法仅需要一部分参数。如果不小心进行,可能会导致方法过多,但也可能通过增加正交性来帮助减少方法数量。例如,考虑
java.util.List
接口。它没有提供在子列表中查找元素的第一个索引或最后一个索引的方法,这两个方法都需要三个参数。而是提供了subList
方法,该方法带有两个参数并返回子列表的视图。该方法可以与indexOf
或lastIndexOf
方法结合使用,以产生所需的功能,每个方法都有一个参数。而且,subList
方法可以与对实例进行操作的任何方法组合以List
对子列表执行任意计算。所得的API具有非常高的功率重量比。
可以说removeRange
没有那么多参数,因此可能不适合使用此方法,但是鉴于有一种方法可以removeRange
通过调用subList
,因此没有理由List
用冗余方法来弄乱接口。
†该AbstractList.removeRange
文件说:
此方法由
clear
对此列表及其子列表的操作调用。重写此方法以利用列表实现的内部功能可以大大改善clear
此列表及其子列表上操作的性能。
另外,请参见OpenJDK的AbstractList.clear
和的实现SubList.removeRange
。
removeRange
调用arraycopy
该ArrayList
版本?hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/e2117e30fb39/src/share/...的numMoved
是0,所以整个arraycopy代码可能已经被放入一个单一的if
(如进行remove
); 区别在于:a)arraycopy是本机调用,会产生开销,b)arraycopy 始终会检查参数的正确性 stackoverflow.com/questions/12594046/…–