- PR -

ArrayList removeRangeの使い方

投稿者投稿内容
yamasa
ベテラン
会議室デビュー日: 2003/02/15
投稿数: 80
投稿日時: 2003-06-11 18:36
yamasaです。

引用:
(株)ぽちさんの書き込み (2003-06-09 10:00) より:
ここでArrayList特有のメソッドを使用したい場合はどうするのでしょうか?

>public void doSomething(List list);

この場合なんか特にそうなのですが
メソッド内ではArrayListの、例えばtrimToSize()とか使用する場合は
(ArrayList)list とキャストする必要があると思います。

しかし、メソッドの引数がListであり、必ずArrayListが入ってくると
は保証されていないですよね?


呼びだされる側が、必ずArrayListオブジェクトを渡して欲しいと望んでいるのなら
ArrayList型の引数を宣言すべきです。

大切なのは、呼び出す側がArrayListをセットして呼び出すから
引数宣言もArrayListにする、なんて安易な考えをしないこと、
つまり、メソッドを「呼び出す側」の都合でシグネチャを決めるのではなく、
「呼び出される側」の立場からシグネチャを考えるようにするわけです。
(株)ぽち
ぬし
会議室デビュー日: 2002/09/10
投稿数: 376
投稿日時: 2003-06-12 08:59
uk様、yamasa様ありがとうございます。

引用:

yamasaさんの書き込み (2003-06-11 18:36) より:

大切なのは、呼び出す側がArrayListをセットして呼び出すから
引数宣言もArrayListにする、なんて安易な考えをしないこと、
つまり、メソッドを「呼び出す側」の都合でシグネチャを決めるのではなく、
「呼び出される側」の立場からシグネチャを考えるようにするわけです。



これで少しわかった気がします。

今後は上記を意識しながら作っていきたいと思います。

その際また疑問が出たらよろしくお願いします。

では。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2003-06-18 10:13
unibon です。こんにちわ。

#以下、便乗質問になります。
#このスレッドができてから、長い間考えていたのですがいまだに分かりません。

ArrayList クラスの removeRange メソッドは、
大元は AbstractList クラスだと思いますが、
なぜこの removeRange メソッドは protected なのでしょうか。
public でも良いと思うのですが。
おそらく継承関係の途中で一旦 protected を public にして広げてしまうと、
その子クラスで再び protected に狭めることができなくなることに由来しているため、
public にすることに慎重になっているためなのだろうとは思うのですが、
イマイチ釈然としません。
AbstractList クラスの段階ですでに removeRange メソッドは
ちゃんと機能するように作られているのだから、
それを呼び出せないように制限する理由が分かりません。

特に AbstractList を extends した ArrayList の段階に限って考えてみても、
(AbstractList にはなく) ArrayList で備わった trimToSize が public になっているのに、
依然として removeRange が protected なのは、なにか意味があるのでしょうか。
#(もちろん、もしそもそも trimToSize が protected だったら意味はない訳ですが。)
nil
会議室デビュー日: 2003/06/17
投稿数: 14
投稿日時: 2003-06-18 15:30
自身やサブリストに効率のいいclear()の実装を提供するため、とAPIドキュメントに書いてありますが。

デフォルトの動作はListIteratorを使用して指定範囲のremove()を繰り返すというものですが、
多くのList実装に対してこれは効率が悪いでしょう。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2003-06-18 16:25
unibon です。こんにちわ。

引用:

nilさんの書き込み (2003-06-18 15:30) より:
自身やサブリストに効率のいいclear()の実装を提供するため、とAPIドキュメントに書いてありますが。


ありがとうございます。
ただ、それを読んでも残る疑問としては、
たとえば ArrayList クラスの ensureCapacity メソッドは、
add メソッドや addAll メソッドの実装のために存在しているもののように見えますが、
これ(ensureCapacity メソッド)は protected ではなく public です。
同様に AbstractList クラスの removeRange メソッドも、
clear メソッドのために存在しているもののように見えますが、
でもこっち(removeRange メソッド)は protected です。
なぜ、このような違いが生じるのかが疑問です。

推測になりますが、コレクションフレームワークの作り手の意図として、
せっかく備えたサブリストの clear メソッドを操作してほしく、
removeRange はあらわに呼んでほしくない、
という理由だけのような気がしてきました。
結局は、使えるんだけど、クラスの作者の意図として、使ってほしくないメソッドというものは多分にあり、
そういうものは public にせず protected にするものなのでしょうか。
クラスの継承の話では、一度 public にすると後々大変なので、
できるだけ public にはしないのが良い、ということを良く聞きますが、
この removeRange も、結局は予期しない継承を阻止するための
なんらかの制約(でも protected なのでオーバライドはできてしまいますが)ということであり、
これはクラスの作者の意図次第であり、各クラスごとにその制約の強さはマチマチ、
というように感じました。
nil
会議室デビュー日: 2003/06/17
投稿数: 14
投稿日時: 2003-06-19 02:02
ArrayListに大量の(個数の分かっている)データを追加する際に
事前にensureCapacityせずに追加していくのはちょっとやりたくないですね

本当はaddAll()が使えればいいのですが、常に相手がCollectionであるわけもないですし。

スキルアップ/キャリアアップ(JOB@IT)