java 如何在 ArrayList<Object> 中查找重复项?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6737212/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 17:04:37  来源:igfitidea点击:

How to find duplicates in an ArrayList<Object>?

javacollections

提问by zengr

This is a pretty common question, but I could not find this part:

这是一个很常见的问题,但我找不到这部分:

Say I have this array list:

假设我有这个数组列表:

List<MyDataClass> arrayList = new List<MyDataClass>;

MyDataClass{
   String name;
   String age;
}

Now, I need to find duplicates on the basis of agein MyDataClassand remove them. How is it possible using something like HashSet as described here?

现在,我需要age在 in的基础上找到重复项MyDataClass并删除它们。怎么可能使用这里描述的 HashSet 之类的东西?

I guess, we will need to overwrite equalsin MyDataClass?

我想,我们需要equals在 MyDataClass 中覆盖?

  1. But, what if I do not have the luxury of doing that?
  2. And How does HashSet actually internally find and does not add duplicates? I saw it's implementation here in OpenJDKbut couldn't understand.
  1. 但是,如果我没有这样做的奢侈呢?
  2. 以及 HashSet 实际上如何在内部查找并且不添加重复项?我在 OpenJDK 中看到了它的实现但无法理解。

回答by aioobe

I'd suggest that you override bothequalsand hashCode(HashSetrelies on both!)

我建议你重写equalshashCodeHashSet依赖于两个!)

To remove the duplicates you could simply create a new HashSetwith the ArrayList as argument, and then clear the ArrayList and put back the elements stored in the HashSet.

要删除重复项,您可以简单地HashSet使用 ArrayList 作为参数创建一个新的,然后清除 ArrayList 并将存储在HashSet.

class MyDataClass {
    String name;
    String age;

    @Override
    public int hashCode() {
        return name.hashCode() ^ age.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof MyDataClass))
            return false;

        MyDataClass mdc = (MyDataClass) obj;
        return mdc.name.equals(name) && mdc.age.equals(age);
    }
}

And then do

然后做

List<MyDataClass> arrayList = new ArrayList<MyDataClass>();

Set<MyDataClass> uniqueElements = new HashSet<MyDataClass>(arrayList);
arrayList.clear();
arrayList.addAll(uniqueElements);

But, what if I do not have the luxury of doing that?

但是,如果我没有这样做的奢侈呢?

Then I'd suggest you do some sort of decorator-class that doesprovide these methods.

然后,我建议你做一些装饰-类的确实提供了这些方法。

class MyDataClassDecorator {

    MyDataClass mdc;

    public MyDataClassDecorator(MyDataClass mdc) {
        this.mdc = mdc;
    }

    @Override
    public int hashCode() {
        return mdc.name.hashCode() ^ mdc.age.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof MyDataClassDecorator))
            return false;

        MyDataClassDecorator mdcd = (MyDataClassDecorator) obj;
        return mdcd.mdc.name.equals(mdc.name) && mdcd.mdc.age.equals(mdc.age);
    }
}

回答by Sam

please see this articlethat explains the importance of equals()and hashCodeto HashSets

请参阅此文章,解释的重要性equals(),并hashCodeHashSets

Also, see this previously answered question

另外,请参阅此先前回答的问题

回答by Daniel

And if you are not able to override "MyDataClass"'s hashCode and equals methods you could write a wrapper class that handles this.

如果您无法覆盖“MyDataClass”的 hashCode 和 equals 方法,您可以编写一个包装类来处理这个问题。

回答by Harsha

public Set<Object> findDuplicates(List<Object> list) {
        Set<Object> items = new HashSet<Object>();
        Set<Object> duplicates = new HashSet<Object>();
        for (Object item : list) {
            if (items.contains(item)) {
                duplicates.add(item);
                } else { 
                    items.add(item);
                    } 
            } 
        return duplicates;
        }