我有一个对象列表/集合,这些对象可能具有相同的属性值,也可能没有。什么是获取具有相等属性的不同对象列表的最简单方法?是否有一种最适合此目的的集合类型?例如,在C#中,我可以使用LINQ执行以下操作:
var recipients = (from recipient in recipientList
select recipient).Distinct();
我最初的想法是使用lambdaj(链接文字),但它似乎不支持此功能。
我有一个对象列表/集合,这些对象可能具有相同的属性值,也可能没有。什么是获取具有相等属性的不同对象列表的最简单方法?是否有一种最适合此目的的集合类型?例如,在C#中,我可以使用LINQ执行以下操作:
var recipients = (from recipient in recipientList
select recipient).Distinct();
我最初的想法是使用lambdaj(链接文字),但它似乎不支持此功能。
return new ArrayList(new HashSet(recipients));
将它们放入一个TreeSet中,并使用自定义比较器来检查您需要的属性:
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));
distinct()
。ListIterable<Integer> integers = Lists.mutable.with(1, 3, 1, 2, 2, 1);
Assert.assertEquals(
Lists.mutable.with(1, 3, 2),
integers.distinct());
distinct()
而不是将 List 转换为 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;
ListAdapter
来获得相同的API。MutableList<Integer> distinct = ListAdapter.adapt(integers).distinct();
Set
。有几种不同的实现:
HashSet
使用对象的 hashCode
和 equals
方法。TreeSet
使用 Comparable
接口定义的 compareTo
方法或者 Comparator
接口定义的 compare
方法。请注意,比较方式必须与 equals
方法一致。更多信息请参考 TreeSet
Java 文档。equals
方法,您必须重写 hashCode
方法,以使两个相等的对象具有相同的哈希码。通常的做法是将其转换为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());
}
});
即使您无法控制收件人类上的equals()
和hashCode()
方法,也可以正常工作。