【问题标题】:How to find duplicates in an ArrayList<Object>?如何在 ArrayList<Object> 中查找重复项?
【发布时间】:2021-08-03 18:45:10
【问题描述】:

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

假设我有这个数组列表:

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

MyDataClass{
   String name;
   String age;
}

现在,我需要在MyDataClass 中根据age 查找重复项并将其删除。如here 所述,如何使用类似 HashSet 的东西?

我想,我们需要覆盖 MyDataClass 中的equals

  1. 但是,如果我没有这样做的奢侈怎么办?
  2. 而HashSet实际上是如何在内部找到并且不添加重复的?我看到了它的实现 here in OpenJDK 但无法理解。

【问题讨论】:

    标签: java collections


    【解决方案1】:

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

    要删除重复项,您可以简单地创建一个新的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);
        }
    }
    

    然后做

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

    【讨论】:

    • 谢谢,这是最有帮助的答案。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:
      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】:

        假设您有一个名为 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));
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-08-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-11-09
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多