google-collections探訪(3) -Immutableなコレクション-

前回:google-collections探訪(2) -Multiset,Multimap- - souta-bot log
お次は大量にあるImmutableなコレクションからいくつかピックアップ。

従来の方法

コレクションを変更不可にしたい場合はCollections.unmodifiableHoge()を使う。
ただしこの変更不可コレクションは元のコレクションへの単なるビューなので、元のコレクションを変更することで変更可能。

public static final Set<String> CURRENCIES;
	
static {
	Set<String> set = new LinkedHashSet<String>();
	set.add("USD");
	set.add("EUR");
	set.add("YEN");
	set.add("GBP");
	CURRENCIES = Collections.unmodifiableSet(set);

	//CURRENCIES.add("CHF"); UnsupportedOperationException

	System.out.println(CURRENCIES); // [USD, EUR, YEN, GBP]
	set.add("CHF");
	System.out.println(CURRENCIES); // [USD, EUR, YEN, GBP, CHF]
}

短くするなら、

public static final Set<String> CURRENCIES
	= Collections.unmodifiableSet(
		new LinkedHashSet<String>(
				Arrays.asList("USD","EUR","JPY","GBP")));

ImmutableSet

上のコードは以下の様に書ける。

// 意図がスッキリ。パフォーマンスもいいらしい。
public static final ImmutableSet<String> CURRENCIES = ImmutableSet.of("USD","EUR","JPY","GBP");

おまけでImmutableSet.copyOf()を使えば防御的コピーも手軽に、意図が明確に書ける。

private Set<T> set = new LinkedHashSet<T>();
	
public ImmutableSet<T> getImmutableSet() {
	return ImmutableSet.copyOf(set);
}

混乱を避けるためにImmutableコレクションに追加するのはImmutableなオブジェクトに限った方が良い。
以下、他のImmutableコレクションもImmutableSetと同じ。

ImmutableMap

public static final ImmutableMap<Integer, String> NUMBER_TO_ENGLISH
	    = ImmutableMap.of(1, "one",
		              2, "two",
		              3, "three",
		              4, "four",
		              5, "five");

ImmutableList

public static final ImmutableList<Integer> HIT_NUMBER = ImmutableList.of(49,77,89);

これでpublic static finalなコレクションがスッキリ書けるようになるね。
参考:Using the Google Collections Library for Java | Java (Programming Language) (1.3K views)