
Javaは戦略的プラットフォーム──ゴールドマン・サックスが実践するJava標準化、オープンソースへの取り組み
Java SE 8のストリームAPIを凌駕するフレームワークとして「GS Collections」を独自開発
講演の後半では、ゴールドマン・サックスが開発し、現在はオープンソースとして公開されているGS Collectionsフレームワークが紹介された。
GS Collectionsは、JavaのCollections APIを拡張したフレームワークであり、前述したように2004年から開発が進められてきた。当時、Javaにはラムダ式が存在しなかったが、GS Collectionsは将来のラムダ式導入を見越して開発されたという。
GS Collectionsは、膨大なリストの処理を効率化するためのフレームワークだ。Java SEには、同様の目的で使われる機能としてJava SE 8で導入された「ストリームAPI(Stream API)」があるが、伊藤氏は「GS Collectionsは、ストリームAPIを凌駕するコレクション・フレームワーク」だと自信をのぞかせる。
「ストリームAPIの紹介では、よく『このAPIがあれば、もうfor文は使わなくてよい』と言われますが、GS Collectionsがあれば、ストリームAPIさえも要りません」(伊藤氏)
ストリームAPIとGS Collectionsの違いを端的に示すために、伊藤氏が紹介したのが次のようなコードだ。
【ストリームAPIとGS Collectionsの違いを端的に示すコードの例】
●ストリームAPIを使ったコード
List<Person> people = Arrays.asList(
new Person("Bob", 17),
new Person("Dave", 23),
new Person("Joe", 32));
List<Person> adults = people.stream()
.filter(person -> person.getAge() > 20) // 抽出処理
.collect(Collectors.<Person>toList());
●GS Collectionsを使ったコード
MutableList<Person> people = Lists.mutable.with(
new Person("Bob", 17),
new Person("Dave", 23),
new Person("Joe", 32));
MutableList<String> names = people.
.select(person -> person.getAge() > 20); // 抽出処理
これらは、いずれもリストから20歳以上の人を抽出するコードだが、抽出処理のお膳立てをするコードが必要なストリームAPIに対して、GS Collectionsでは抽出処理そのものを簡潔に書くことができる。
「ストリームAPIは遅延評価なので、必ず終端操作が必要であり、冗長なコードになりがちです。複雑な加工を行う際には遅延評価が効きますが、コレクションの操作では1つの条件で抽出する場合も多いでしょう。そうしたとき、即時実行が可能なGS Collectionsならば、余計なコードを省いてスパッと書けるのです」(伊藤氏)
次の図は、GS Collectionsの設計コンセプトを簡単な図で示したものだ。
この図にあるとおり、GS Collectionsでは、コレクションのコンテナごとにRichIterableインタフェースを導入し、そこからReadable、Mutable、Immutableの各インタフェースを派生させている。
「JDK標準のコレクションでは、add、put、removeなど要素の変更が可能なメソッドを備えるミュータブルなインタフェースのみが用意されていますが、GS Collectionsには要素を変更できるインタフェースMutableと、要素固定のインタフェースImmutableの両方が用意されています。複数のスレッドで並列処理を行う場合は、インタフェースImmutableを使うことで安全に実装できます」(伊藤氏)
このほか、GS Collectionsでは豊富なイテレーション・パターンを使うことができ、新しいコレクション型も提供されている。
【GS Collectionsに用意されている新しいコレクション型】
コレクション | 説明 |
---|---|
Bag | 重複を含むリスト用のコレクション。重複カウント機能を備える |
BiMap | 双方向のKey/Value型コレクション。ValueもKeyとして利用できる |
Multimap | コレクションをValueに持つKey/Value型のコレクション |
メモリ使用効率の高さもGS Collectionsの特筆すべき点だ。
「JDK標準のHashSet、HashMapはメモリの使用効率が悪いため、それらを置き換えるために、GS CollectionsにはUnifiedSetやUnifiedMapといった独自のコレクションが用意されています」(伊藤氏)
次に示すグラフは、JDKのHashMapとGS CollectionsのUnifiedSet、TroveのTHashSetのメモリ消費量を比較したものだ。
Troveも効率の良さで定評のあるコレクション・フレームワークだが、メモリ使用効率ではGS Collectionsが一段上を行く。ちなみに、GS Collectionsではメモリ消費量を減らすために、Javaには存在しないプリミティブ型のコレクションも提供している。
以上のようにGS Collectionsの特徴を紹介すると、伊藤氏は最後に次のように呼びかけて講演を締めくくった。
「GS Collectionsは膨大なデータを効率良く処理するために開発されていますが、API自体は平易なため、ライトユースにも使えます。GS Collectionsの使い方を学ぶためのトレーニング教材として『GS Collections Kata』も公開していますので、ぜひ試してみてください」(伊藤氏)