2012-04-16 18 views
12

इस प्रश्न को पोस्ट करने से पहले, मुझे किसी भी तरह का प्रश्न here पोस्ट किया गया। लेकिन जवाब एक स्ट्रिंग पर आधारित था। हालांकि, मेरे पास एक अलग स्थिति है। मैं स्ट्रिंग को हटाने की कोशिश नहीं कर रहा हूं लेकिन एक और ऑब्जेक्ट जिसे पुरस्कार YearSource कहा जाता है। इस वर्ग में वर्ष कहा जाता है एक int विशेषता है। तो मैं साल के आधार पर डुप्लीकेट को हटाना चाहता हूं। यानी यदि वर्ष 2010 में एक से अधिक बार उल्लेख किया गया है, तो मैं उस पुरस्कार YearSource ऑब्जेक्ट को हटाना चाहता हूं। मैं उसे कैसे कर सकता हूँ?कस्टम जावा ऑब्जेक्ट के आधार पर सूची से डुप्लीकेट को कैसे हटाया जा सकता है?

+0

जावा 8 रास्ता भी काफी अच्छा है: http://stackoverflow.com/questions/23699371/java-8-distinct-by-property – JDC

उत्तर

45

एक क्षेत्र के आधार पर तत्व के रूप में (संरक्षण आदेश) इस प्रकार है दूर करने के लिए सबसे आसान तरीका:

Map<Integer, AwardYearSource> map = new LinkedHashMap<>(); 
for (AwardYearSource ays : list) { 
    map.put(ays.getYear(), ays); 
} 
list.clear(); 
list.addAll(map.values()); 
+1

धन्यवाद। यह मेरी समस्या हल हो गया। हालांकि मैंने आपके कोड की पहली पंक्ति को मानचित्र map = new LinkedHashMap () में बदल दिया है; .... अन्यथा यह संकलित नहीं होगा। – WowBow

+5

क्षमा करें, '<>' वाक्यविन्यास केवल जावा 7 में काम करता है। –

+0

अच्छी चाल। धन्यवाद मेरी समस्या हल करें। – James

0

आप एक कुंजी के रूप में साल के साथ अपने वस्तुओं एक नक्शे के इस्तेमाल कर सकते हैं और स्टोर:

Map<Integer, AwardYearSource> map = new HashMap<Integer, AwardYearSource>(); 
map.put(someAwardYearSource1.getYear(), someAwardYearSource1); 
map.put(someAwardYearSource2.getYear(), someAwardYearSource2); 

etc. 

अंत में नक्शा साल से अनन्य मानों में शामिल होंगे, जो आप मान विधि के साथ कॉल कर सकते हैं:

Collection<AwardYearSource> noDups = map.values(); 
0

कुंजी प्रकार के रूप में कुंजी प्रकार और अपनी कक्षा के रूप में int के साथ हैश मैप ऑब्जेक्ट बनाएं। तब सूची पर पुनरावृति और का उपयोग कर नक्शा करने के लिए प्रत्येक तत्व सम्मिलित करें:

mymap.put(source.year, source); 

फिर origianl सूची से सभी तत्वों को हटाने और नक्शे पर पुनरावृति और सूची में प्रत्येक तत्व सम्मिलित करें।

+0

वास्तव में? क्या आप शायद अधिक जानकारी प्रदान कर सकते हैं? हालांकि कम से कम एक इटरेटर अनावश्यक है - कुछ अन्य उत्तरों को देखें। और यदि किसी थ्रेडेड संदर्भ में उपयोग किया जाता है, तो इसका कुछ दुष्प्रभाव होगा। –

+0

शायद आपने इस टिप्पणी को गलत उत्तर पर पोस्ट किया है? मुझे अपने समाधान में कोई भी इटरेटर नहीं दिख रहा है और यह काफी धागा सुरक्षित है। – smichak

+0

आप स्पष्ट रूप से पुनरावृत्ति का जिक्र करते हैं, और आप कम से कम एक _implicit_ (संकलक उत्पन्न, प्रत्येक निर्माण के मामले में) इटरेटर का उपयोग करने जा रहे हैं। यदि इसे अपनी स्वयं की विधि में पैक किया जा रहा है (जो यह होना चाहिए), तो मूल सूची से आइटम को निकालना ** बिल्कुल नहीं ** थ्रेडसेफ है। –

1

एक अन्य तरीका आपकी ऑब्जेक्ट के लिए hashCode() और equals(Object obj) ओवरराइड करना होगा। चूंकि इसमें केवल एक फ़ील्ड है जिसका उपयोग आप समानता निर्धारित करने के लिए करना चाहते हैं, यह बहुत सरल है। कुछ की तरह:

public boolean equals(Object obj) { 
    if (obj == null || !(obj instanceof AwardYearSource)) { 
    return false; 
    } 
    return (this.year == ((AwardYearSource)obj).year); 
} 
public int hashCode() { 
    return this.year; 
} 

तो फिर तुम सिर्फ वस्तुओं के सभी एक Set में छड़ी डुप्लिकेट को निकालने के कर सकते हैं:

Set<AwardYearSource> set = new Set<AwardYearSource>(); 

set.add(new AwardYearSource(2011)); 
set.add(new AwardYearSource(2012)); 
set.add(new AwardYearSource(2011)); 

for (AwardYearSource aws : set) { 
    System.out.println(aws.year); 
} 
0

अपने AwardYearSource वर्ग ओवरराइड के बराबर होती है और hashCode विधि (ग्रहण दोनों उत्पन्न कर सकते हैं), तो आप उन्हें एक सेट में जोड़ सकते हैं। सेट में कोई डुप्लीकेट नहीं होगा।

public class AwardYearSource 
{ 
    private final int year; 

    public AwardYearSource(int year) 
    { 
     this.year = year; 
    } 

    @Override 
    public int hashCode() 
    { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + year; 
     return result; 
    } 

    @Override 
    public boolean equals(Object obj) 
    { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     AwardYearSource other = (AwardYearSource) obj; 
     if (year != other.year) 
      return false; 
     return true; 
    } 

    @Override 
    public String toString() 
    { 
     return String.valueOf(year); 
    } 


    public static void main(String[] args) 
    { 
     Set<AwardYearSource> set = new HashSet<AwardYearSource>(); 
     set.add(new AwardYearSource(2000)); 
     set.add(new AwardYearSource(2000)); 
     set.add(new AwardYearSource(2000)); 
     set.add(new AwardYearSource(2000)); 

     System.out.println(set); 
    } 
} 

आउटपुट [2000] है। सेट में केवल एक आइटम।

1

काफी सरलता से। हालांकि मैप संस्करणों के बारे में मुझे कुछ चीजें हैं (मुझे शक नहीं है कि वे काम करेंगे, यह किसी भी तरह से ओवरकिल जैसा लगता है - हालांकि यह संस्करण जरूरी नहीं है कि इस संबंध में कोई बेहतर हो)।
उत्तर कार्यात्मक है, और थ्रेडसेफ (माना जाता है कि AwardYearSource अपरिवर्तनीय है)।

public static List<AwardYearSource> removeDuplicateYears(
              final Collection<AwardYearSource> awards) { 
    final ArrayList<AwardYearSource> input = new ArrayList<AwardYearSource>(awards); 
    // If there's only one element (or none), guaranteed unique. 
    if (input.size() <= 1) { 
     return input; 
    } 
    final HashSet<Integer> years = new HashSet<Integer>(input.size(), 1); 
    final Iterator<AwardYearSource> iter = input.iterator(); 
    while(iter.hasNext()) { 
     final AwardYearSource award = iter.next(); 
     final Integer year = award.getYear(); 
     if (years.contains(year)) { 
      iter.remove(); 
     } else { 
      years.add(year); 
     } 
    } 
    return input;  

} 
+0

बहुत सारे फाइनल –

0
Set<Integer> set = new HashSet<>(); 
list.removeIf(i -> set.contains(i.getYear()) ? true : !set.add(i.getYear())); 

यह मदद करनी चाहिए जिसमें, दोहराव कुछ संपत्ति (या गुण के संयोजन) के आधार पर फैसला किया है, इस मामले में साल। उम्मीद है की यह मदद करेगा।