簡體   English   中英

Java - 不同的對象列表

[英]Java - Distinct List of Objects

我有一個列表/對象集合,可能有也可能沒有相同的屬性值。 獲得具有相同屬性的對象的明確列表的最簡單方法是什么? 一種集合類型最適合此目的嗎? 例如,在C#中,我可以使用LINQ執行以下操作。

var recipients = (from recipient in recipientList
                 select recipient).Distinct();

我最初的想法是使用lambdaj( 鏈接文本 ),但它似乎不支持這一點。

return new ArrayList(new HashSet(recipients));

使用接口Set<T> (類T可能需要自定義.equals()方法,您可能必須自己實現.equals() )。 通常, HashSet開箱即用:它使用Object.hashCode()Object.equals()方法來比較對象。 對於簡單的對象來說,這應該是唯一的。 如果沒有,你將不得不相應地實現T.equals()T.hashCode()

有關幫助實現equals和hashcode的庫,請參閱下面的Gaurav Saini的評論。

將它們放在一個TreeSet中,該TreeSet包含一個自定義Comparator,它會檢查您需要的屬性:

SortedSet<MyObject> set = new TreeSet<MyObject>(new Comparator<MyObject>(){

    public int compare(MyObject o1, MyObject o2) {
         // return 0 if objects are equal in terms of your properties
    }
});

set.addAll(myList); // eliminate duplicates

Java 8:

recipients = recipients.stream()
    .distinct()
    .collect(Collectors.toList());

請參閱java.util.stream.Stream#distinct

命令保留上述響應的版本

return new ArrayList(new LinkedHashSet(recipients));

如果您正在使用Eclipse Collections ,則可以使用distinct()方法。

ListIterable<Integer> integers = Lists.mutable.with(1, 3, 1, 2, 2, 1);
Assert.assertEquals(
    Lists.mutable.with(1, 3, 2),
    integers.distinct());

使用distinct()而不是轉換為Set然后返回List的優點是distinct()保留了原始List的順序,保留了每個元素的第一次出現。 它是通過使用Set和List實現的。

MutableSet<T> seenSoFar = Sets.mutable.with();
int size = list.size();
for (int i = 0; i < size; i++)
{
    T item = list.get(i);
    if (seenSoFar.add(item))
    {
        targetCollection.add(item);
    }
}
return targetCollection;

如果無法將原始List轉換為Eclipse Collections類型,則可以使用ListAdapter獲取相同的API。

MutableList<Integer> distinct = ListAdapter.adapt(integers).distinct();

注意:我是Eclipse Collections的提交者。

您可以使用Set 有幾個實現:

  • HashSet使用對象的hashCodeequals
  • TreeSet使用compareTo (由Comparable定義)或compare (由Comparator定義)。 請記住,比較必須與equals一致。 有關詳細信息,請參閱TreeSet JavaDocs。

還要記住,如果重寫equals ,則必須覆蓋hashCode ,使得兩個equals對象具有相同的哈希碼。

這樣做的普通方法是轉換為Set,然后轉換回List。 但是你可以使用Functional Java 如果你喜歡Lamdaj,你會愛上FJ。

recipients = recipients
             .sort(recipientOrd)
             .group(recipientOrd.equal())
             .map(List.<Recipient>head_());

您需要為收件人, recipientOrd定義訂單。 就像是:

Ord<Recipient> recipientOrd = ord(new F2<Recipient, Recipient, Ordering>() {
  public Ordering f(Recipient r1, Recipient r2) {
    return stringOrd.compare(r1.getEmailAddress(), r2.getEmailAddress());
  }
});

即使您沒有在Recipient類上控制equals()hashCode() ,也可以正常工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM