我有一个列表/对象集合,可能有也可能没有相同的属性值。获得具有相同属性的对象的明确列表的最简单方法是什么?一种集合类型最适合此目的吗?例如,在C#中,我可以使用LINQ执行类似下面的操作。
var recipients = (from recipient in recipientList
select recipient).Distinct();
我最初的想法是使用lambdaj(link text),但它似乎不支持这个。
答案 0 :(得分:37)
return new ArrayList(new HashSet(recipients));
答案 1 :(得分:28)
使用接口Set<T>
的实现(类T可能需要自定义.equals()
方法,您可能必须自己实现.equals()
。通常HashSet
开箱即用:它使用Object.hashCode()
和Object.equals()
方法来比较对象。对于简单的对象来说,这应该是唯一的。如果没有,则必须相应地实施T.equals()
和T.hashCode()
。
有关帮助实现equals和hashcode的库,请参阅下面的Gaurav Saini的评论。
答案 2 :(得分:20)
将它们放在一个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
答案 3 :(得分:11)
Java 8:
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
if (scanResult != null) {
String contents = scanResult.getContents();
if (contents != null) {
orderNum.setText("Order Number: " + contents);
new CheckQR(this,orderStatus).execute(contents);
} else {
//failed
}
}
答案 4 :(得分:7)
订购保留上述回复的版本
return new ArrayList(new LinkedHashSet(recipients));
答案 5 :(得分:7)
如果您使用的是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;
如果您无法将原始列表转换为Eclipse集合类型,则可以使用ListAdapter
来获取相同的API。
MutableList<Integer> distinct = ListAdapter.adapt(integers).distinct();
注意:我是Eclipse Collections的提交者。
答案 6 :(得分:4)
您可以使用Set
。有几个实现:
HashSet
使用对象的hashCode
和equals
。TreeSet
使用compareTo
(由Comparable
定义)或compare
(由Comparator
定义)。请注意,比较必须与equals
一致。有关详细信息,请参阅TreeSet
JavaDocs。另请注意,如果覆盖equals
,则必须覆盖hashCode
,以使两个equals对象具有相同的哈希码。
答案 7 :(得分:3)
这样做的普通方法是转换为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()
,也能正常工作。
答案 8 :(得分:2)
实际上lambdaj通过selectDistinctArgument方法
实现了这个功能