【问题标题】:Why is Java's AbstractList's removeRange() method protected?为什么 Java 的 AbstractList 的 removeRange() 方法受到保护?
【发布时间】:2011-01-18 08:27:21
【问题描述】:

有谁知道,为什么AbstractList(以及ArrayList)中的 removeRange 方法是protected?它看起来像是一个定义明确且有用的操作,但要使用它,我们还是不得不继承 List 实现。

有什么隐藏的理由吗?对我来说似乎很莫名。

【问题讨论】:

    标签: java list collections arraylist protected


    【解决方案1】:

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

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

    这实际上在幕后调用removeRange


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

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

    有人可能会争辩说removeRange 没有那么多参数,因此可能不适合这种处理方式,但鉴于有一种方法可以通过subList 调用removeRange,因此没有理由使用冗余方法使List 接口混乱。


    AbstractList.removeRange 文档说:

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

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

    【讨论】:

    • 好的,可以这样,但是为什么?好像很别扭单个元素可以直接从列表中删除,为什么不可以多个元素呢?
    • @Joonas:Effective Java 第 2 版的第 40 条描述了这样做的基本原理。如果您没有这本书,我会粘贴到相关部分。
    • +1(已回答问题)。然而,仅仅因为给出了理由并不意味着它是有意义的。缩短参数列表的过程阻碍了开发人员理解 API 中可用操作的能力,这与最初缩短列表的原因背道而驰。
    • 对于 java 来说非常典型。让我们让它变得最复杂,效率最低。
    • 作为旁注,您是否注意到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/…
    猜你喜欢
    • 1970-01-01
    • 2019-10-09
    • 2015-05-02
    • 2014-10-09
    • 1970-01-01
    • 2011-10-02
    • 2011-01-18
    • 2023-04-09
    相关资源
    最近更新 更多