読者です 読者をやめる 読者になる 読者になる

覚えたら書く

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

com.google.common.collect.Multiset

Guava Java

Guavacom.google.common.collect.Multisetの利用サンプルです。
Multisetは、java.util.Setとは異なり要素の重複を許可し、
各要素が何個登録されているかを取得するためのcountメソッドなどを提供します。

以下のようなAPIを提供します

  • Multiset#count - 指定要素の登録数を返却する。(返却値が2以上なら重複しているということ)
  • Multiset#remove - 指定の要素を削除します(集合内の要素の個数を1減算します)。対象要素が2個以上登録されている場合、完全には集合内からは削除されず、containsメソッドもtrueを返却します。
  • Multiset#elementSet - Multiset内の要素を保持するjava.util.Setを返却します。

例えば、特定の単語を保持しているListから各単語が何個保持されているかを把握したい場合に、Multisetを使わないと以下のようなコードになったりします。

List<String> words = Lists.newArrayList("hello", "dog", "cat", "red", "hello", "hello", "dog", "blue", "blue");

// Multisetを使わずにList内に含まれる各単語の出現回数をカウントする場合
// 以下のような処理を使うことになるかな
Map<String, Integer> counts = new HashMap<>();
for (String word : words) {
    Integer count = counts.get(word);
    if (count == null) {
        counts.put(word, 1);
    } else {
        counts.put(word, count + 1);
    }
}

System.out.println("hello Number of occurrences: " + counts.get("hello"));
System.out.println("dog Number of occurrences: " + counts.get("dog"));
System.out.println("cat Number of occurrences: " + counts.get("cat"));

Multisetを使えばもっとシンプルにコードを書くことができます。(以下のサンプル参照)

まず以下のコードで単語が格納されたMultiset(変数名=wordMultiSet)を生成します。

List<String> words = Lists.newArrayList("hello", "dog", "cat", "red", "hello", "hello", "dog", "blue", "blue");

Multiset<String> wordMultiSet = HashMultiset.create(words);

その後に以下の各サンプルが実行されているものとしてください


各単語の出現回数をカウントする

countメソッドを使うことでMultiset内の各要素の格納数(重複数)を知ることができます

■サンプル

System.out.println("hello Number of occurrences: " + wordMultiSet.count("hello"));
System.out.println("dog Number of occurrences: " + wordMultiSet.count("dog"));
System.out.println("cat Number of occurrences: " + wordMultiSet.count("cat"));

■実行結果

hello Number of occurrences: 3
dog Number of occurrences: 2
cat Number of occurrences: 1


Iteratorを使って各要素にアクセスする

Iteratorを使ってMultisetの各要素にアクセスすると重複したものは複数回出力されます

■サンプル

// Iteratorを使って各要素にアクセスすると重複したものは複数回出力される
for (String word : wordMultiSet) {
    System.out.println(word);
}

■実行結果

red
blue
blue
cat
hello
hello
hello
dog
dog


要素の追加

通常のSetと同様にaddメソッドを実行することで要素を追加できます。同じ要素を複数回addすると、その分countの結果が増えます

■サンプル

// 新しい単語を追加
wordMultiSet.add("godzilla");
System.out.println("(1) godzilla contains: " + wordMultiSet.count("godzilla"));

// すでに登録済みの単語をさらに追加
wordMultiSet.add("godzilla");
System.out.println("(2) godzilla contains: " + wordMultiSet.count("godzilla"));
wordMultiSet.add("godzilla");
System.out.println("(3) godzilla contains: " + wordMultiSet.count("godzilla"));

■実行結果

(1) godzilla count: 1
(2) godzilla count: 2
(3) godzilla count: 3


要素をremoveする

removeするとcountが1減る

■サンプル

// removeするとcountが1減る(元々2以上ある場合containsはtrueを返す)

// wordMultiSet.count("hello")  ->  3

wordMultiSet.remove("hello");

System.out.println("hello contains: " + wordMultiSet.contains("hello"));
System.out.println("hello Number of occurrences: " + wordMultiSet.count("hello"));

■実行結果

hello contains: true
hello Number of occurrences: 2


削除する数を指定してremoveする

removeメソッドでは削除対象の要素と削除する数を指定することができます

■サンプル

// wordMultiSet.count("hello")  ->  2

wordMultiSet.remove("hello", 2);

System.out.println("hello contains: " + wordMultiSet.contains("hello"));
System.out.println("hello Number of occurrences: " + wordMultiSet.count("hello"));

■実行結果

hello contains: false
hello Number of occurrences: 0


Multiset内の要素を格納したSetを返す

Multiset内の要素を格納したSetを返す。その際には当然Set内の要素に重複は無い状態となります

■サンプル

// wordMultiSet内の要素の状態は {red=1, blue=2, cat=1, dog=2}

Set<String> wordSet = wordMultiSet.elementSet();

for (String word : wordSet) {
    System.out.println(word);
}

■実行結果

red
blue
cat
dog




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

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.common.collect.HashMultiset;
import com.google.common.collect.Lists;
import com.google.common.collect.Multiset;

public class MultisetClient {

    public static void main(String[] args) {

        List<String> words = Lists.newArrayList("hello", "dog", "cat", "red", "hello", "hello", "dog", "blue", "blue");

        // Multisetを使わずにList内に含まれる各単語の出現回数をカウントする場合
        // 以下のような処理を使うことになるかな
        Map<String, Integer> counts = new HashMap<>();
        for (String word : words) {
            Integer count = counts.get(word);
            if (count == null) {
                counts.put(word, 1);
            } else {
                counts.put(word, count + 1);
            }
        }
        System.out.println("hello Number of occurrences: " + counts.get("hello"));
        System.out.println("dog Number of occurrences: " + counts.get("dog"));
        System.out.println("cat Number of occurrences: " + counts.get("cat"));

        // Multisetを使って各単語の出現回数をカウントする場合は以下の通り
        System.out.println("### Multiset.count execute");
        // Multiset#countで各要素の個数をカウントしてみる
        Multiset<String> wordMultiSet = HashMultiset.create(words);
        System.out.println("hello Number of occurrences: " + wordMultiSet.count("hello"));
        System.out.println("dog Number of occurrences: " + wordMultiSet.count("dog"));
        System.out.println("cat Number of occurrences: " + wordMultiSet.count("cat"));


        // Iteratorを使って各要素にアクセスすると重複したものは複数回出力される
        System.out.println("### Multiset.iterator execute");
        for (String word : wordMultiSet) {
            System.out.println(word);
        }

        // 要素の追加(複数回実施すればcountの結果も増える)
        System.out.println("### Multiset.add execute");
    // 新しい単語を追加
        wordMultiSet.add("godzilla");
        System.out.println("(1) godzilla count: " + wordMultiSet.count("godzilla"));
    // すでに登録済みの単語をさらに追加
        wordMultiSet.add("godzilla");
        System.out.println("(2) godzilla count: " + wordMultiSet.count("godzilla"));
        wordMultiSet.add("godzilla");
        System.out.println("(3) godzilla count: " + wordMultiSet.count("godzilla"));

        // removeするとcountが1減る(元々2以上ある場合containsはtrueを返す)
        System.out.println("### Multiset.remove execute");
        wordMultiSet.remove("hello");
        System.out.println("hello contains: " + wordMultiSet.contains("hello"));
        System.out.println("hello Number of occurrences: " + wordMultiSet.count("hello"));

        // 削除する数を指定してremoveすることも可能
        System.out.println("### Multiset.remove execute specifies the number");
        wordMultiSet.remove("hello", 2);
        System.out.println("hello contains: " + wordMultiSet.contains("hello"));
        System.out.println("hello Number of occurrences: " + wordMultiSet.count("hello"));

        // Multiset内の要素を格納したSetを返す(当然、返却されたSet内の要素の重複は無い)
        System.out.println("### Multiset.elementSet execute");
        Set<String> wordSet = wordMultiSet.elementSet();
        for (String word : wordSet) {
            System.out.println(word);
        }
    }
}



関連エントリ