如何在ArrayList <object>?</object>中查找重复项

时间:2011-07-18 18:00:05

标签: java collections

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

说我有这个数组列表:

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

MyDataClass{
   String name;
   String age;
}

现在,我需要根据age中的MyDataClass找到重复项并删除它们。如何使用HashSet这样的内容如here所述?

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

  1. 但是,如果我不那么奢侈呢?
  2. HashSet如何实际内部查找并且不添加重复项?我看到了它的实施here in OpenJDK,但无法理解。

5 个答案:

答案 0 :(得分:16)

我建议您覆盖 equalshashCodeHashSet依赖于两者!)

要删除重复项,您只需使用ArrayList作为参数创建一个新的HashSet,然后清除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);
    }
}

然后再做

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

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

但是,如果我没有那么奢侈呢?

然后我建议你做一些 提供这些方法的装饰类。

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);
    }
}

答案 1 :(得分:1)

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

答案 2 :(得分:1)

请参阅此article,其中解释了equals()hashCodeHashSets

的重要性

此外,请参阅此前回答的question

答案 3 :(得分:0)

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;
        }

答案 4 :(得分:0)

假设您有一个名为 Person 的类,它有两个属性:idfirstName。 在它的类中编写这个方法:

String uniqueAttributes() {
  return id + firstName;
}

getDuplicates() 方法现在应该是这样的:

public static List<Person> getDuplicates(final List<Person> personList) {
  return getDuplicatesMap(personList).values().stream()
      .filter(duplicates -> duplicates.size() > 1)
      .flatMap(Collection::stream)
      .collect(Collectors.toList());
}

private static Map<String, List<Person>> getDuplicatesMap(List<Person> personList) {
  return personList.stream().collect(groupingBy(Person::uniqueAttributes));
}