JavaのAbstractListのremoveRange()メソッドが保護されているのはなぜですか?


98

誰もが何か考えを持っていますか、なぜAbstractListの(そしてArrayListの)removeRangeメソッドがなぜprotectedですか?非常に明確に定義された便利な操作のように見えますが、それでも、それを使用するには、List実装をサブクラス化する必要があります。

隠された根拠はありますか?私にはかなり不可解なようです。

回答:


163

はい、それはあなたが外部コードから範囲を削除する方法ではないためです。代わりに、次のようにします。

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

これは実際removeRangeには舞台裏を呼び出します。


OPは、なぜパブリックAPIのremoveRange一部ではないのかを尋ねListます。その理由は、Effective Java 2nd edのItem 40に記載されており、ここで引用します。

過度に長いパラメータリストを短縮する方法は3つあります。1つは、メソッドを複数のメソッドに分割することです。各メソッドは、パラメーターのサブセットのみを必要とします。不注意に行うと、メソッドの数が多くなりすぎる可能性がありますが、直交性を高めることでメソッド数を減らすのにも役立ちます。たとえば、java.util.Listインターフェースについて考えてみます。サブリスト内の要素の最初または最後のインデックスを検索するメソッドは提供されません。どちらも3つのパラメーターが必要です。代わりにsubList、2つのパラメーターを取り、サブリストのビューを返すメソッドを提供します。このメソッドをindexOfor lastIndexOfメソッドと組み合わせると、それぞれに単一のパラメーターがあり、目的の機能を実現できます。さらに、subListメソッドは、インスタンスを操作する任意のメソッドと組み合わせてList、サブリストに対して任意の計算を実行できます。結果のAPIは、非常に高い電力対重量比を持っています。

これremoveRangeはそれほど多くのパラメーターを持たないため、おそらくこの処理の候補ではないと主張できますが、をremoveRange介して呼び出す方法があることを考えると、冗長なメソッドでインターフェースsubListを混乱させる理由はありませんList


AbstractList.removeRangeドキュメントは言います:

このメソッドはclear、このリストとそのサブリストの操作によって呼び出されます。このメソッドをオーバーライドしてリスト実装の内部を利用すると、このリストとそのサブリストに対する操作のパフォーマンスを大幅に向上させることができclearます。

また、のOpenJDKのの実装を参照してくださいAbstractList.clearSubList.removeRange


9
OK、それはそのようにできますが、なぜですか?ぎこちないようです。単一の要素をリストから直接削除できますが、それでは複数の要素を削除しないのはなぜですか?
Joonas Pulakka、2010

1
@Joonas:効果的なJavaの項目40、第2版では、この理由を説明しています。本がない場合は、関連セクションに貼り付けます。
Chris Jester-Young

21
+1(質問への回答)。ただし、理論的根拠が与えられているからといって、それが理にかなっているとは限りません。パラメータリストを短縮するプロセスは、APIで利用可能な操作を理解する開発者の能力を妨げます。これは、リストが最初に短縮された理由に直接作用します。
Sam Harwell

3
Javaの典型的な例です。最も複雑で最も効果の低いものにしましょう。
トマーシュZato -復活モニカ

2
余談ですが、リストの最後までの範囲でバージョンが使用されているremoveRangeと、arraycopy不必要にが呼び出されることに気づきArrayListましたか?hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/e2117e30fb39/src/share/…これnumMovedは0なので、arraycopyコード全体を1つにまとめることができますif(で行ったようにremove)。違いは、のarraycopyはない)B、)のarraycopyがオーバーヘッドを発生、ネイティブの呼び出しであるということです常に正しさのためのparamsをチェック stackoverflow.com/questions/12594046/...
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.