![](/img/trans.png)
[英]How to create a list of distinct objects using list of different objects having properties using java streams
[英]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());
命令保留上述響應的版本
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
使用對象的hashCode
和equals
。 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()
,也可以正常工作。
實際上lambdaj通過selectDistinctArgument方法實現了這個功能
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.