为什么Java的AbstractList的removeRange()方法受到保护?


Answers:


163

是的,因为这不是您从外部代码中删除范围的方式。相反,请执行以下操作:

list.subList(start, end).clear();

这实际上removeRange是在幕后。


OP询问为什么removeRange不属于List公共API。原因在《有效Java第二版》的第40条中进行了描述,在此引用:

有三种缩短简短参数列表的技术。一种是将方法分解为多种方法,每种方法仅需要一部分参数。如果不小心进行,可能会导致方法过多,但也可能通过增加正交性来帮助减少方法数量。例如,考虑java.util.List接口。它没有提供在子列表中查找元素的第一个索引或最后一个索引的方法,这两个方法都需要三个参数。而是提供了subList方法,该方法带有两个参数并返回子列表的视图。该方法可以与indexOflastIndexOf方法结合使用,以产生所需的功能,每个方法都有一个参数。而且,subList方法可以与对实例进行操作的任何方法组合以List对子列表执行任意计算。所得的API具有非常高的功率重量比。

可以说removeRange没有那么多参数,因此可能不适合使用此方法,但是鉴于有一种方法可以removeRange通过调用subList,因此没有理由List用冗余方法来弄乱接口。


AbstractList.removeRange文件说:

此方法由clear对此列表及其子列表的操作调用。重写此方法以利用列表实现的内部功能可以大大改善clear此列表及其子列表上操作的性能。

另外,请参见OpenJDK的AbstractList.clear和的实现SubList.removeRange


9
好的,可以这样做,但是为什么呢?似乎很尴尬。单个元素可以直接从列表中删除,那么为什么不选择多个元素呢?
乔纳斯·普拉卡

1
@Joonas:Effective Java(第二版)的第40项描述了这一原理。如果您没有这本书,我会在相关部分中粘贴。
克里斯·杰斯特·杨

21
+1(问题已回答)。但是,仅仅给出理由并不意味着就有意义。缩短参数列表的过程阻碍了开发人员理解API中可用操作的能力,这直接与首先缩短列表的原因背道而驰。
山姆·哈威尔

3
因此对于Java很典型。让我们使其最复杂,最不有效。
托马什Zato -恢复莫妮卡

2
附带说明一下,您是否注意到,当使用该版本直至列表末尾时,会不必要地removeRange调用arraycopyArrayList版本?hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/e2117e30fb39/src/share/...numMoved是0,所以整个arraycopy代码可能已经被放入一个单一的if(如进行remove); 区别在于:a)arraycopy是本机调用,会产生开销,b)arraycopy 始终会检查参数的正确性 stackoverflow.com/questions/12594046/…–
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.