覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。twitter: @yyoshikaw

com.google.common.collect.ImmutableSet

Guavacom.google.common.collect.ImmutableSetの利用サンプルです。
ImmutableSetは不変(Immutable)なSetです。
ImmutableSetへのadd等の変更操作を行うとUnsupportedOperationExceptionがスローされます。

以下のAPIなどを利用してImmutableSetを生成します

  • ImmutableSet#copyOf - 指定の配列やCollectionから新しいImmutableSetを生成します
  • ImmutableSet#of - 登録する要素を指定してImmutableSetを生成します

サンプルコードで試したのは以下の通りです。


コピー元のCollectionに追加操作をしてもImmutableSetへ影響がない

ImmutableSet#copyOfで生成したSetはコピー元のCollectionに要素を追加しても、生成したImmutableSetの内容に変化はありません
それに対して、Collections#unmodifiableSetを使用した場合は、コピー元のCollectionに要素を追加すると生成したSetにも影響がでます。

■サンプル

Set<String> names = new LinkedHashSet<>();
names.add("taro");
names.add("jiro");

Set<String> builtInSet = Collections.unmodifiableSet(names);
Set<String> guavaSet = ImmutableSet.copyOf(names);

names.add("saburo");

// 生成元のSetに対して要素を追加してもImmutableSetには追加されない
System.out.println("Built In Set: " + builtInSet);    // ->  [taro, jiro, saburo]
System.out.println("Guava Set: " + guavaSet);         // ->  [taro, jiro]

■実行結果

Built In Set: [taro, jiro, saburo]
Guava Set: [taro, jiro]


ImmutableSetへのadd操作は失敗する

ImmutableSetへ変更操作(add等)を実行すると UnsupportedOperationException がスローされます

■サンプル

ImmutableSet<Integer> set1 = ImmutableSet.of(1, 2, 3, 4);

try {
    set1.add(5);
} catch (UnsupportedOperationException e) {
    e.printStackTrace();
}

System.out.println("set1: " + set1);

■実行結果

java.lang.UnsupportedOperationException
    at com.google.common.collect.ImmutableCollection.add(ImmutableCollection.java:201)
    at sample.guava.ImmutableSetClient.main(ImmutableSetClient.java:31)
set1: [1, 2, 3, 4]


ImmutableSet.Builderを使って新しい要素を追加したImmutableSetを生成

ImmutableSetに要素を追加したい場合は、ImmutableSet.Builderを利用して新しいImmutableSetを生成します

■サンプル

Set<String> set = ImmutableSet.of("ABC", "DEF", "GHI");

ImmutableSet<String> newSet = new ImmutableSet.Builder<String>()
                .addAll(set)
                .add("JKL")
                .build();

System.out.println("newSet: " + newSet);

■実行結果

newSet: [ABC, DEF, GHI, JKL]




試したソースコードの全体は以下です。

import com.google.common.collect.ImmutableSet;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;

public class ImmutableSetClient {

    public static void main(String[] args) {

        // Collections#unmodifiableSetとImmutableSet#copyOfで生成したSetの動きの違いを確認
        System.out.println("### Difference between Collections#unmodifiableSet and ImmutableSet#copyOf");
        Set<String> names = new LinkedHashSet<>();
        names.add("taro");
        names.add("jiro");

        Set<String> builtInSet = Collections.unmodifiableSet(names);
        Set<String> guavaSet = ImmutableSet.copyOf(names);

        names.add("saburo");

        // 生成元のSetに対して要素を追加してもImmutableSetには追加されない
        System.out.println("Built In Set: " + builtInSet);    // ->  [taro, jiro, saburo]
        System.out.println("Guava Set: " + guavaSet);         // ->  [taro, jiro]

        System.out.println("### ImmutableSet#of");
        ImmutableSet<Integer> set1 = ImmutableSet.of(1, 2, 3, 4);
        try {
            set1.add(5);
        } catch (UnsupportedOperationException e) {
            e.printStackTrace();
        }
        System.out.println("set1: " + set1);

        // ImmutableSet.Builderを使って元のSet+新しい要素のImmutableSetを生成
        System.out.println("### ImmutableSet.Builder#build");
        Set<String> set = ImmutableSet.of("ABC", "DEF", "GHI");
        ImmutableSet<String> newSet = new ImmutableSet.Builder<String>()
                        .addAll(set)
                        .add("JKL")
                        .build();
        System.out.println("newSet: " + newSet);
    }
}