Google Collections Library 〜immutable collection編〜

Google Collections Library とは

Google Collections Library とはJDKのコレクションフレームワークを自然な形で拡張したコレクションライブラリです。2009年末1.0がリリースされました。プロジェクトは以下のサイトでホストされています。
http://code.google.com/p/google-collections/

ライセンスは Apache License 2.0 となっています。Google Collections Library は Google社の Java コアライブラリである guava ライブラリに含まれる予定となっています。なお、JDK は 1.5以降を対象としています。

今回は Google Collections Library から immutable な colection について見ていきます。

ImmutableSet

JDK のコアライブラリを使用して Immutable な Set を作成するには以下のように Collections の unmodifiableSet でラップします。

public static final Set<Integer> LUCKY_NUMBERS;
static {
    Set<Integer> set = new LinkedHashSet<Integer>();
    set.add(4);
    set.add(8);
    set.add(15);
    set.add(16);
    set.add(23);
    set.add(42);
    LUCKY_NUMBERS = Collections.unmodifiableSet(set);
}

または、もう少し短く書くと、

public static final Set<Integer> LUCKY_NUMBERS
    = Collections.unmodifiableSet (
        new LinkedHashSet<Integer> (
            Arrays.asList(4, 8,15,16,23,42)));


上記は、Google Collections Library の ImmutableSet を使用すると、以下のように簡素に記述することができます。

public static final ImmutableSet<Integer> LUCKY_NUMBERS
    = ImmutableSet.of(4, 8, 15, 16, 23, 42);

ImmutableSet のインスタンスは static ファクトリメソッドにて得ます。以下のようなメソッドが提供されています。

ImmutableSet.of()        // 空のImmutableSetを作成
ImmutableSet.of(a)       // 要素としてaを含んだシングルトンなImmutableSetを作成
ImmutableSet.of(a, b, c) // 要素としてa,b,cを含んだImmutableSetを作成


また、既存のコレクションから ImmutableSet を作成するには以下の copyOf が提供されています。

ImmutableSet.copyOf(Iterable)
ImmutableSet.copyOf(Iterator)

防御的コピーは通常以下のようになりますが、

private final Set<Integer> luckyNumbers;
public Dharma(Set<Integer> numbers) {
    luckyNumbers = Collections.unmodifiableSet {
        new LinkedHashSet<Integer> (numbers)};
}
public Set<Integer> getLuckyNumbers() {
    return luckyNumbers;
}

ImmutableSet.copyOfにて以下のように書くことができます。

private final ImmutableSet<Integer> luckyNumbers;
public Dharma(Set<Integer> numbers) {
    luckyNumbers = ImmutableSet.copyOf(numbers);
}
public ImmutableSet<Integer> getLuckyNumbers() {
    return luckyNumbers;
}

ImmutableMap

JDK のコアライブラリを使用して Immutable な Met を作成するには同じように Collections の unmodifiableSet でラップします。

public static final Map<String, Integer> ENGLISH_TO_INT;
static {
    Map<String, Integer> map = new LinkedHashMap<String, Integer>();
    map.put("four", 4);
    map.put("eight", 8);
    map.put("fifteen", 15);
    map.put("sixteen", 16);
    map.put("twenty-three", 23);
    map.put("forty-two", 42);
    ENGLISH_TO_INT = Collections.unmodifiableMap(map);
}

Google Collections Library では以下のように書きます。

public static final ImmutableMap<String, Integer>
    ENGLISH_TO_MAP = new ImmutableMap.Builder<String, Integer>()
        .put("four", 4)
        .put("eight", 8)
        .put("fifteen", 15)
        .put("sixteen", 16)
        .put("twenty-three", 23)
        .put("forty-two", 42)
        .build();

ImmutableMap.Builder にてメソッド連結し、最後に build します。

マップの要素が5個までは of が用意されているため以下のように書くことができます。

public static final ImmutableMap<String, Integer>
    ENGLISH_TO_MAP = ImmutableMap.of(
        "four",          4,
        "eight",         8,
        "fifteen",      15,
        "sixteen",      16,
        "twenty-three", 23);

[[]]