Google Collections Library 1.0 Final バージョンは、2009 年 12 月 30 日にリリースされた。http://code.google.com/p/google-collections/ でダウンロードすることができる。ライブラリは Google エンジニアの Kevin Bourrillion 氏と Jared Levy 氏が発明したものである。Google 以外のエンジニア(Doug Lea 氏、Josh Block 氏、Bob Lee 氏らのように)やオープンソースコミュニティ全体の貢献のおかげで、最近の数年における実質的な成長が見られる。
ライブラリは、Java プラットフォームのビルトインコレクションライブラリを拡張することを目指している。JDK コレクションライブラリ – 現在の標準として – は、java.util.* パッケージにある。それは主に少数のインタフェース、java.util.Collection (親インタフェース)、java.util.Set、java.util.SortedSet、java.util.Map、java.util.List、に根付いている。これらのインタフェースは、背後にある Sun が出荷する様々な実装との間の契約を決定付けている。java.util.Set は、順序付けされていない、ユニークな(重複の無い)要素のコレクションをゆるく定義している。java.util.SortedSet は、順序付けされた、ユニークな要素のコレクションを表現する。java.util.Map は、キーと値の関連 – 他の言語ではよくディクショナリと呼ばれる – を定義し、java.util.List は、要素の数が可変である順序付けられた要素のコレクションを定義する。Josh Bloch 氏が Sun で働いていた時に設計した、元のフレームワークは、三つのアイデアを中心としている。それらは、拡張可能な方法でコレクションを操作することを可能にする、インタフェース、実装(具象と抽象の両方)、アルゴリズムである。これらのインタフェースは、以前の JDK で提供されていたクラス(java.util.Vector、java.util.Hashtable、その他) の実質的なオーバーホールとして導入された。Josh Bloch 氏は、この 2008 Google Techcast において Google Collections Libray は彼が満足している方向に開発されたことを示した。
Google Collections Library は、新しい便利な実装や不変コレクション実装を含む並列性に関して焦点を当てたライブラリのセットを提供している。“変更できない(unmodifiable)”( JDK の java.util.Collections クラスの unmodifiable* ファクトリメソッドで保証される) は、コレクションのクライアント – ユーザ – がコレクションを決して変更できないことを保証するだけであるが、“不変性(Immutability)”は、システム内の他のどんなアクタ – 実装それ自身でさえ ” がコレクションの状態を変更できないことを保証する。ほとんどの場合、実装は JDK ラッパーではない。しかし良くに調整された、メモリに敏感な、インタフェースの再実装である。Google Collections Library は、オブジェクトの作成を可能にする、多くの静的ファクトリメソッドやビルダ (たいていは両方) を提供している。これらは時々、型宣言の冗長性を解消するためのシンプルなユーティリティメソッドになる。
import com.google.common.collect.*;
...
HashSet<String> hashSet = Sets.newHashSet();
LinkedHashSet<String> linkedHashSet = Sets.newLinkedHashSet();
ArrayList<String> arrayList = Lists.newArrayList();
LinkedList<String> linkedList = Lists.newLinkedList();
他では、静的ファクトリメソッドやビルダは、実装にはパブリックなコンストラクタが存在しないので使用される。サブクラスを作成することは、多くのケースで不変性の契約がサブクラスにより妥協されてしまうかもしれないので望ましくない。Google Collections Library における Immutable* インタフェースは、JDK に基づくインタフェースの契約でそれらの意味を実装するのと同じように、コレクションが不変性の保証を持っている事をコレクションのクライアントに対して示している。
import com.google.common.collect.*;
...
ImmutableSet<Integer> immutableSet = ImmutableSet.of(1, 2, 3, 4, 5);
ImmutableList<String> immutableList = ImmutableList.of("a,b,c,d,e,f,g".split(","));
ライブラリは、MultiMap と MultiSet コレクションを含むいくつかのユニークなライブラリ実装も提供している。それらは、コレクションの要素数や頻度を問い合わせることができるオブジェクトのコレクションを表現している。したがって、一つのキーに関連付けられた複数の値を保存するために、以下のように使用することができる。
Multimap<String, Integer> personAndFavoriteNumbers = ArrayListMultimap.create();
personAndFavoriteNumbers.put("josh", 42);
personAndFavoriteNumbers.put("josh", 7);
Collection<Integer>numbers = personAndFavoriteNumbers.get("josh"); // doesn't return Integer
System.out.println(numbers .size()) ; // == 2
get(String)
は、キーに関連付けられたビューを返すことを示している。もし、マップ内に指定したキーの値が存在しなければ、空のコレクションが返されるだろう。もしビューコレクションにアイテムを追加したならば、それらは Multimap に反映される。
Collection<Integer>numbers = personAndFavoriteNumbers.get("josh");
System.out.println(numbers .size()) ; // == 2
numbers.add( 0) ;
System.out.println(numbers .size()) ; // == 3
System.out.println(personAndFavoriteNumbers.get("josh").size() ) ; // == 3
全てカスタムインタフェースとして利用可能な多くの並列実装もまたある。
ConcurrentHashMultiset<String> concurrentHashMultiset =
ConcurrentHashMultiset.create(Arrays.asList("a,b,c,d,e,f".split(",")));
Guugle Collections Library は、さまざまな関数プログラミングのイディオムとして動作するための優雅さを com.google.common.base.Predicate クラスを使用することで提供している。
…
Iterable<Integer> filteredSet = Iterables.filter( someIterable, new Predicate<Integer>(){
public boolean apply( Integer integer) {
return integer > 0 ;
}
}) ;
ライブラリの適合を話しておくと、ライブラリは、Google において本番環境への配置の実績と 25,000 以上の徹底的なユニットテストスイートを持っている。Google Collections Library はとても有望ではあるものの、代替物がある。JDK の各々の iteration は、新しいコレクションの発展により恩恵を受ける。Apache の commons collections プロジェクトもまたいくつかの興味深いコレクションの、このライブラリより何年もさかのぼる実装を持っている。けれども、それらには Generics と親和性が無いことに気づくだろう。将来を見ると、Kevin Bourrillion 氏は、プロジェクトの意思は、このライブラリを正式化し、その後 JCP へ提出することであると言っている。