SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

Jakarta Commonsを使ってJDKクラスを拡張する:パート1

Commons Validator/Collections/Chain/Functors/Langの利用

Collections

 Commons Collectionsは、これだけを単独の記事として取り上げてもよいほど大きなトピックです。本稿ではAPIについて概説するにとどめ、最も一般的な実例を示します。

 JDKにJava Collections Frameworkがあるのに、なぜCommons Collectionsが必要なのかと疑問を持つ人もいるかもしれません。Collectionsは、Java Collections Frameworkのクラスとインターフェイスを拡張し、機能強化するものです。実のところ、私はこれをJDKの一部にすべきだとさえ思っています。

 私が特に好んで使用している機能をいくつか挙げておきます。

  • バッグインターフェイス
  • 固定サイズ、デュアル、およびLRUのマップ
  • オブジェクト配列およびマップのイテレータ
  • マップのMultiKey
  • APIを使いやすくする多数のユーティリティクラス
  • 大部分のクラスの動作をカスタマイズできるデコレータ

 Collectionsのクラスは次のようなパッケージに編成されています。

  • org.apache.commons.collections
  • org.apache.commons.collections.bag
  • org.apache.commons.collections.bidimap
  • org.apache.commons.collections.buffer
  • org.apache.commons.collections.collection
  • org.apache.commons.collections.comparators
  • org.apache.commons.collections.functors
  • org.apache.commons.collections.iterators
  • org.apache.commons.collections.keyvalue
  • org.apache.commons.collections.list
  • org.apache.commons.collections.map
  • org.apache.commons.collections.set

org.apache.commons.collections

 「org.apache.commons.collections」パッケージには、他のパッケージで実装されているインターフェイスと、コレクションクラスまたはコレクションクラスのデコレートバージョンをインスタンス化するためのファクトリとして機能するユーティリティクラスが含まれています。ArrayStackBeanMapExtendedPropertiesFastArrayListFastHashMapFastTreeMapといった注目すべきクラスが含まれています。これらのクラスの詳細情報はjavadocに網羅されていますが、表1で各クラスの実際の用法を簡単に紹介しておきます。

表1 「org.apache.commons.collections」パッケージ内の注目すべきクラス
コレクションクラス実際の用法
ArrayStackArrayStackはシングルスレッド環境で使用するためにArrayListをスタック実装にしたものです。たとえば、特定のメソッドの中でだけ何かの処理にスタックを使用したいという場合は、この実装を使用した方がJDK-1.4.2のVectorを使ったスタック実装よりも有利です。
BeanMapSwing GUIウィジェットのJButtonと同様、このクラスを使用すると、マップさえもJava Beanとして扱うことができます。アプリケーションのデータソースや一連の設定プロパティを表現するGUIをデザインする際に、マップを画面上でドラッグアンドドロップすることができます。
ExtendedPropertiesこのパッケージで私が最も気に入っているクラスです。設定プロパティをロードするためのloadメソッドを持つjava.util.Propertiesに似ていますが、こちらの実装には次のような利点があります。
・同じプロパティキーに複数の値を持たせることができます。
・値を異なる行に分割することができます。
・非文字列値を取得するための便利なヘルパーメソッドがあります。
たとえば、getFloatメソッドはfloat型のプロパティを取得します。そのため、設定プロパティ値を解析するためにラッパーメソッドを書く必要はありません。
FastArrayList
FastHashMap
FastTreeMap
大部分の操作が読み取り専用ならば、これらのクラスをマルチスレッド環境で使用できます。これらのクラスは、それぞれArrayListHashMapTreeMapをベースにしています。

org.apache.commons.collections.bag

 org.apache.commons.collections.bagクラスは、オブジェクトの複数のコピーをListに追加するという要件を備えたアプリケーションでとても役に立ちます。こうした状況では、通常は、オブジェクトをArrayListに追加し、特定の型の追加オブジェクトの数を判定する際には毎回反復処理を行うという方法が使われています。この要件に該当する好例はオンラインショッピングカートです。このアプローチの欠点は、メモリと速度の面でパフォーマンスが劣ることです。

 この要件に対処するには、オブジェクトのコピーを1つだけ保持し、同じ型のエントリが新たに追加されるたびにカウントを増やしていくというやり方が好ましいでしょう。それにはCommons CollectionsのHashBagクラスとTreeBagクラスが適しています(それぞれHashMapTreeMapをベースにしています)。

 ソースコードの「in.co.narayanan.commons.collections.bag」パッケージを見ると、バッグの実際の用法がわかります。このサンプルでは、さまざまなオペレーティングシステムのソフトウェアライセンスの注文を処理し、バッグ内の注文された製品を表現しています。

 これらのクラスでは、もっと具体的なバージョンやデコレータが利用できます。詳細についてはjavadocを参照してください。

org.apache.commons.collections.bidimap

 たいていのJava開発者は、キー/値のキーを取り出したい場合には、2つのHashMapを用意し、1つ目のHashMapの値を2つ目のHashMapにキーとして渡す、という方法を使用してきました。通常、名前と値を平等に扱いたければ、このテクニックを使用する必要があります。このケースでは値さえもキーになり得ます。

 org.apache.commons.collections.bidimapは、PeopleSoftとSiebelのコマンド処理エンジンを統合するプロトタイプアダプタです(ただし、双方に同等のコマンドが存在することが前提となります)。このアダプタの関連クラスは「in.co.narayanan.commons.collections.bidimap」パッケージに含まれています。まず、サンプル内のクラスSiebelPeopleSoftConnectorのコードをひととおり見てみてください。このクラスはアダプタとして働き、コマンドマッピングをBidiMap内に保持します。Siebelコマンドを処理する要求が到着すると、BidiMapから対応するPeopleSoftコマンドが取得され、PeopleSoftコマンドエンジンに渡されます。PeopleSoftコマンドでは逆の処理が行われます。このサンプルに含まれているのはアプリケーションのスケルトンだけです。

 請負で設計をする場合は、このクラスの修正不能バージョン(開発者が内容を変更できないもの)を使用すると便利です。これにより、開発者が内容を処理しているときに誤りを犯す危険性を大幅に減らすことができます。

org.apache.commons.collections.buffer

 コレクションから特定の順序でオブジェクトを取り除きたい場合は、バッファインターフェイスの実装を利用することができます。注目すべきクラスとして、CircularFifoBufferPriorityBufferBoundedFifoBufferBlockingBufferなどを挙げることができます。いずれにもデコレートバージョンがあります。

 パッケージ「in.co.narayanan.commons.collections.buffer」にバッファサンプルがあります。これはCircularFifoBufferクラスの例を示しています。このクラスは移動ウィンドウと考えることができます。コレクションのサイズは固定しており、満杯になるとオブジェクトが先入れ先出し(FIFO)方式で削除されます。

 このアプリケーションの目的は、リモートサーバーにパフォーマンスデータを報告することです。パフォーマンスデータは監視に使用されるだけなので、データが失われてもそれほど問題にはなりません。パフォーマンスデータを報告するクライアントアプリケーションは、ReportPerformanceDataクラスをインスタンス化し、reportPerformanceメソッドを呼び出す必要があります。パフォーマンスデータは循環バッファに追加されます。

 ReportTaskクラスはパフォーマンスデータオブジェクトを削除し、それをパフォーマンスサーバーに送ります。報告タスクを非同期に開始するためにJava 1.5の並行処理ユーティリティクラスThreadPoolExecutorが使用されるので、バッファ内に報告すべきデータがあればデータが報告されます。

org.apache.commons.collections.collection

 「org.apache.commons.collections.collection」パッケージにはデコレータクラスが含まれています。これらのクラスはjava.util.Collectionインターフェイスを直接実装しています。そのため、Collectionインターフェイスを実装しているクラスならどのクラスでも、これらのデコレータを利用することができます。PredicatedCollectionCompositeCollectionSynchronizedCollectionTransformedCollectionTypedCollectionUnmodifiableCollectionなどがよく使われるクラスです。表2に、これらのデコレータをどのような場合に使用するかを示します。

表2 「org.apache.commons.collections.collection」パッケージ内のよく使われるクラス
デコレータクラス使用する状況
PredicatedCollectionコレクションへのオブジェクトの追加を"amount >= $15000"などの条件で制限したいとき。このクラスをインスタンス化するには、条件を別オブジェクトとして定義します。これはプレディケイトとして呼び出され、decorateファクトリメソッドに引数として渡されます。
CompositeCollectionコレクションのコレクションを作成し、オブジェクトの追加または削除を統一的な方法で行いたいとき。
SynchronizedCollection既存のコレクションをスレッドセーフにしたいとき。
TransformedCollectionコレクションへの追加時に常にオブジェクトの形式を変換したいとき(たとえばStringからIntegerに変換するなど)。
TypedCollectionコレクションに追加するオブジェクトの型を制限したいとき。これはJava 1.5のgenericsに似ています。
UnmodifiableCollection既存のコレクション参照への修正を制限したいとき。

org.apache.commons.collections.comparators

 このパッケージにはさまざまな再利用可能クラスが含まれており、コレクション内でオブジェクトをソートするときに役立ちます。特に注目したいのがNullComparatorクラスとFixedOrderComparatorクラスです(表3を参照)。

表3 NullComparatorクラスとFixedOrderComparatorクラス
再利用可能なクラス機能
NullComparator配列またはリストの中でエントリをソートする際にnullエントリを最後部に移動します。
FixedOrderComparatorコレクション内での順序をあらかじめ定義されたリストに戻します。

org.apache.commons.collections.functors

 「org.apache.commons.collections.functors」パッケージについては、後のセクションで詳しく説明します。

org.apache.commons.collections.iterators

 「org.apache.commons.collections.iterators」パッケージ内の多くのクラスはjava.util.Iteratorインターフェイスを実装しています。MapIteratorArrayIteratorCollatingIteratorLoopingIteratorIteratorUtilsなどが最も役に立つクラスです。このパッケージ内のクラスを利用するには、IteratorUtilsクラス内のメソッドをよく調べる必要があるでしょう。

org.apache.commons.collections.keyvalue

 「org.apache.commons.collections.keyvalue」パッケージ内のMultiKeyクラスは非常に有用です。アプリケーション内でドメインオブジェクトを作成し、それを複合主キーと対にしてマップに格納したい場合は、対象レコードの主キーを構成する値を渡してMultiKeyのインスタンスを作成します。その後、このインスタンスをドメインオブジェクトを格納するためのマップに渡します。

 このパッケージのその他の一般的な用法として、ロケール固有のエントリをマップに格納するという例が挙げられます。この場合は、実際のキーとロケール名からキーが構成されます。

org.apache.commons.collections.list

 「org.apache.commons.collections.list」パッケージ内の注目すべきクラスは、TreeListFixedSizeListNodeCachingLinkedListCursorableLinkedListTransformedListPredicatedListです。これらのクラスのことは、javadocを見ればすぐに分かります。

org.apache.commons.collections.map

 「org.apache.commons.collections.map」パッケージ内の注目すべきクラスは、CaseInsensitiveMapCompositeMapFixedSizeMapFlat3MapLazyMapLinkedMapLRUMapMultiKeyMapPredicatedMapSingletonMapStaticBucketMapです。これらのクラスのことは、javadocを見ればすぐにわかります。

org.apache.commons.collections.set

 「org.apache.commons.collections.set」パッケージ内の注目すべきクラスは、CompositeSetListOrderedSetMapBackedSetPredicatedSetTransformedSetTypedSetUnmodifiableSetです。これらのクラスのことは、javadocを見ればすぐにわかります。

次のページ
Chain

この記事は参考になりましたか?

japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Narayanan A.R.(Narayanan A.R.)

テスト駆動開発、アジャイル方法論、Javaテクノロジ、およびデザインパターンの熱烈な擁護者。Javaテクノロジを使ったソフトウェアのデザインおよび開発に携わって数年になる。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/283 2006/04/11 19:09

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー