2013-11-04 13 views
8

मैंने देखा (और सराहना की है) कि गुवा के ImmutableMap.Builder बिल्डर में डुप्लिकेट कुंजी जोड़े जाने पर विफल होने में विफल रहता है। फिर भी वही व्यवहार (डुप्लिकेट तत्व जोड़ना) ImmutableSet के साथ सफल होता है।ImmutableSet डुप्लिकेट क्यों देता है, लेकिन ImmutableMap

क्या इस अंतर का कोई कारण है, और 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 एस अन्य 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); 
+0

यह समझ में आता है, धन्यवाद! – dimo414

संबंधित मुद्दे