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

Joo*_*kka 96 java collections list protected arraylist

有没有人有任何想法,为什么AbstractList(以及在ArrayList中)中的removeRange方法是protected?它看起来像一个非常明确和有用的操作,但是,使用它,我们仍然被迫继承List实现.

有一些隐藏的理由吗?对我来说似乎很莫名.

Chr*_*ung 159

是的,因为这不是你从外部代码中删除范围的方式.相反,这样做:

list.subList(start, end).clear();
Run Code Online (Sandbox Code Playgroud)

这实际上removeRange是在幕后调用.


OP询问为什么removeRange不是List公共API的一部分.原因在Effective Java 2nd ed的第40项中描述,我在这里引用它:

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

有人可能会说removeRange没有那么多的参数,因此可能是不适合这种治疗的候选者,但考虑到有调用的方式removeRange通过subList,没有任何理由来弄乱List接口与冗余的方法.


AbstractList.removeRange文件说:

此方法clear由此列表及其子列表上的操作调用.重写此方法以利用列表实现的内部可以显着提高clear此列表及其子列表上的操作的性能.

另外,请参阅OpenJDK的实现AbstractList.clearSubList.removeRange.

  • +1(回答问题).然而,仅仅因为给出了基本原理并不意味着它是有道理的.缩短参数列表的过程阻碍了开发人员理解API中可用操作的能力,这直接影响了列表首先缩短的原因. (20认同)
  • 好吧,它可以这样做,但*为什么*?看起来很尴尬.单个元素可以直接从列表中删除,为什么不是多个元素呢? (9认同)
  • 这是java的典型特征.让它变得最复杂,效率最低. (3认同)
  • 作为旁注,您是否注意到,当在跨越列表末尾的范围上使用“ArrayList”版本时,“removeRange”会不必要地调用“arraycopy”?http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/e2117e30fb39/src/share/classes/java/util/ArrayList.java#l631 `numMoved` 为 0,所以整个 arraycopy 代码可以'已被放入单个 `if`(如在 `remove` 中所做的那样);不同之处在于a)arraycopy是本机调用,会产生开销,b)arraycopy确实*总是*检查参数的正确性http://stackoverflow.com/questions/12594046/java-native-method-source-code (2认同)