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

是的,这种行为是故意的。这是一种思考方式:Sets 经常是从其他Collections 创建的,尤其是 s List,它们可能有重复。ImmutableSet.copyOf(Sets.newHashSet(element))如果可能有重复,要求用户编写会非常尴尬 - 并且效率低下。另一方面,Maps 通常是从其他Maps 构建的,它们不能有重复的键。

如果你想禁止重复元素,你最好的选择是

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 回答