Java - 不同的对象列表

时间:2009-06-19 20:17:21

标签: java list collections

我有一个列表/对象集合,可能有也可能没有相同的属性值。获得具有相同属性的对象的明确列表的最简单方法是什么?一种集合类型最适合此目的吗?例如,在C#中,我可以使用LINQ执行类似下面的操作。

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

我最初的想法是使用lambdaj(link text),但它似乎不支持这个。

9 个答案:

答案 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
        }
    }

请参阅java.util.stream.Stream#distinct

答案 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使用对象的hashCodeequals
  • 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)