10

ImmutableMap.Builder重複したキーがビルダーに追加されている場合、Guava のビルドに失敗することに気付きました (そして感謝しています!) 。それでも、同じ動作 (重複した要素を追加する) は で成功しImmutableSetます。

この違いの理由はありImmutableSetますか?同じ失敗動作で を構築する良い方法はありますか?

テストケース:

import static org.testng.Assert.*;
import org.testng.annotations.Test;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;

public class ImmutableDuplicatesTest
{
    @Test(expectedExceptions=IllegalArgumentException.class) // Note failure
    public void mapDuplicates() {
        ImmutableMap.Builder<String, String> map = ImmutableMap.builder();
        map.put("a", "a");
        map.put("b", "b");
        map.put("a", "c");
        assertEquals(map.build().size(), 2);
    }

    @Test // Passes normally
    public void setDuplicates() {
        ImmutableSet.Builder<String> set = ImmutableSet.builder();
        set.add("a");
        set.add("b");
        set.add("a");
        assertEquals(set.build().size(), 2);
    }
}
4

1 に答える 1

10

はい、この動作は意図的なものです。これについての 1 つの考え方は次のとおりです。 Sets は他の s から作成されることが多くCollection、特にListは重複している可能性があります。ImmutableSet.copyOf(Sets.newHashSet(element))重複がある可能性がある場合にユーザーに書き込みを要求するのは、非常に扱いにくく、非効率的です。一方、Mapは通常Map、重複キーを持つことができない他の から構築されます。

重複要素を禁止したい場合、最善の策は次のようなものです

Set<E> set = new LinkedHashSet<E>();
for (E e : input) {
  if (!set.add(e)) {
    throw new IllegalArgumentException();
  }
}
return ImmutableSet.copyOf(set);
于 2013-11-04T18:02:47.807 に答える