Bagが欲しい...
2008.05.15
とおねだりする話では全然ないです。
集計みたいなタイプのプログラムを書いていると、
要素の重複をOKにするコレクションが欲しいけども、List で線形探査するのはアクセススピードを考えると勘弁して!
という状況が生まれます。java.util のインターフェイスの中では、
- List だと、要素の重複はOKだけども、contains() は線形探査。
- Set だと、要素の重複は不可だけども、contains() はハッシュコードなり二進木なり速い手段を使って探査する。
というように、帯に短したすきに長し...という状況です。これを解決するのは、jakarta-commons(あれ、今はApache-commons の方が良さそうですが)のcollections 中にある、Bag というインターフェイスです。実際この org.apache.commons.collections.Bag は、
要素の重複がOKの List みたいな Set
なのです....ですから、この実装クラスとして、o.a.c.collections.bag.HashBag(HashSet相当)とか、o.a.c.collections.bag.TreeBag(TreeSet相当)があるので、たとえば「データが追加された時点で、ソートされている List」みたいな使い方を、TreeBag はすることができてしまいます。これ結構強力でしょ!
実際のところ、Collections フレームワークと、Java5 の新 for 構造のおかげで、
今ループで順にアクセスしようとしてる対象が、配列なのか List なのか Set なのか全然クライアント側では気にしなくてイイ!
という状況になっています。とすれば、
コーラー側は整列したモノを期待しているのだけども、手元にあるのは非整列状態しかない。ゲッタで呼ばれるたびにソートするのか(効率が悪い)? それともソートしたものを内部で保持する格好にして、一度ソートしたらソレを返すようにするのか(同期しなくなる可能性がある)?
という悩ましい状況を、「そもそも整列された状態で保持すればいいじゃん!」とキレイに解決することができるようになるわけです。Set だと重複値の問題で List と同一視できない、という落とし穴を、この Bag は回避できるのです。
あと、commons-collections の使い勝手のいいオブジェクトとしては、MultiMap(重複した値を一つのキーに与えられるMap)があったりしますから、こっちも Bag とノリは似てますね! 今一つ地味(でも、さまざまな大オープンソース・プロジェクトでフツーに使われている...) な commons-collections ですけども、使うと結構イイ使い心地です。ぜひぜひお使いください。
あと設計が Decorator ベースで、かなりイロイロできるようになっているのも特徴ですね。均質化Bag とか、変更不可とか、あるいは 3.0 からは Predicate によるちょっとした Map 関数風処理とか、結構地味ながらも着実な進化を遂げているみたいですね!
投稿者 : 杉浦 こずえ | 投稿日時 : 2008.05.15 15:24
あすなろBLOGのトラックバック・コメントは承認制になっています。
すぐにブログに反映されませんので、ご了承ください。





