2013-11-04 5 views
8

は私が気づいた(と感謝!)グァバのImmutableMap.Builderは、重複キーをビルダーに追加されている場合はビルドに失敗したことをImmutableMapません。しかし、同じ動作(重複要素を追加)はImmutableSetで成功します。この違いの理由、および同じ障害時の動作と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); 
    } 
} 
+1

のようなものです私の推測では、セットを使用すると、入力と同じことを二度だけ、それの一つのコピーを持つことができるように設計されている、ということでしょう。しかしマップで、あなたが新しい値に同じキーをマッピングする場合、それは古いものを上書きし、これは動作 – Cruncher

+0

を意図することはできませんしかし、値は関係ありません同じであるかどうか、それは重複に高速失敗しますキー。 – dimo414

答えて

10

はい、この動作は意図的です。ここではそれについて考えての一つの方法です:Set sが頻繁に他のCollection sから作成され、特にList、重複を有していてもよいです。重複している可能性がある場合は、ユーザーにImmutableSet.copyOf(Sets.newHashSet(element))と書くように要求するのは非常に面倒で非効率的です。一方、Map sが一般的に重複したキーを持つことができない他のMap S、から構築されています。

あなたが重複要素を禁止したい場合は、あなたの最善の策は、

Set<E> set = new LinkedHashSet<E>(); 
for (E e : input) { 
    if (!set.add(e)) { 
    throw new IllegalArgumentException(); 
    } 
} 
return ImmutableSet.copyOf(set); 
+0

それは感謝します、ありがとう! – dimo414

関連する問題