2012-04-16 12 views
12

, ben bir şekilde benzer bir soru here yayınlanmıştır bulundu. Ama cevap bir String'e dayanıyordu. Ancak burada farklı bir durum var. String'i çıkarmaya çalışmıyorum ama AwardYearSource adlı başka bir nesne. Bu sınıfın yıl adında bir int özniteliği var. Bu nedenle, yıl bazında kopyaları kaldırmak istiyorum. Yani 2010 yılı birden fazla kez belirtilmişse, o AwardYearSource nesnesini kaldırmak istiyorum. Bunu nasıl yapabilirim?Yinelenen bir tür değil, özel bir java nesnesini temel alan bir listeden çiftler nasıl kaldırılır? Bu soruyu göndermeden önce

+0

Java 8 yolu da oldukça güzel: http://stackoverflow.com/questions/23699371/java-8-distinct-by-property – JDC

cevap

45

bir alana bağlı elemanlar (koruyarak sipariş) aşağıdaki gibidir kaldırmak için en basit yolu: Bir anahtar olarak yıl nesnelerinizi haritayı kullanmak ve depolayabilir

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

teşekkür ederiz. Sorunumu çözdü. Ancak kodunuzun ilk satırını Harita harita = yeni LinkedHashMap (); .... aksi takdirde derleme yapmaz. – WowBow

+5

Maalesef '<>' sözdizimi sadece Java 7. –

+0

İyi numara çalışır. Teşekkürler sorunumu çöz. – James

0

:

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

etc. 
sonunda

harita değerleri yöntemi ile çağırabilir, hangi yıl benzersiz değerler içerecektir:

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

Anahtar türü olarak int ve sınıfın değer türü olarak bir HashMap nesnesi oluşturun. Sonra liste yineleme ve kullanarak haritaya her öğe eklemek:

mymap.put(source.year, source); 

Sonra Origianl listeden tüm öğeleri kaldırmak ve harita üzerinde yineleme ve listeye her elemanını yerleştirin.

+0

Gerçekten mi? Daha fazla bilgi verebilir misiniz? Yineleyicilerin en az biri gereksiz olsa da - diğer cevapların bazılarına bakın. Ve bu dişli bir bağlamda kullanılıyorsa, bazı kötü yan etkileri olacaktır. –

+0

Belki bu yorumu yanlış cevaba yazdınız mı? Çözümlerimde hiç yineleyici görmüyorum ve iş parçacığı güvenli. – smichak

+0

Yinelenen yinelemeden bahsediyorsunuz ve en az bir _implicit_ (her yapı için oluşturulmuş derleyici) yineleyici kullanacaksınız. Bu, kendi yönteminde (olması gereken) paketlenmişse, orijinal listeden öğeleri kaldırmak ** kesinlikle DEĞİL ** threadafe. –

1

başka bir yolu da nesne için hashCode() ve equals(Object obj) geçersiz olacaktır. Eşitliği belirlemek için kullanmak istediğiniz tek bir alan olduğundan, bu oldukça basittir. Bir şey gibi:

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; 
} 

Sonra sadece çiftleri kaldırmak için bir Set içine tüm nesneleri yapışabilir:

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

, ardından AwardYearSource sınıf geçersiz kılar eşittir ve karma kodudur yöntemleri (Eclipse hem üretebilir) ise bunları bir Set'e ekleyebilirsiniz. Set hiçbir kopya içermeyecektir.

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); 
    } 
} 

Çıktı [2000]. Sette sadece bir öğe var.

1

Oldukça basit. Bir şey harita versiyonları hakkında beni rahatsız etse de (çalışacaklarından şüphe etmeme rağmen, bu bir şekilde overkill gibi görünüyor - bu versiyonun bu konuda daha iyi olmasına rağmen).
Yanıt (AwardYearSource iletmenin olduğunu varsayarak), fonksiyonel ve evre olan. Bu durumda

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

Çok fazla final –

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

Bu çoğaltma belli bir özelliği (veya özelliklerin kombinasyonuna) göre karar olup, burada yardımcı olmalıdır, yıl. Bu yardımcı olur umarım.

İlgili konular