【问题标题】:Find Duplicate Objects in an java arraylist在 java 数组列表中查找重复对象
【发布时间】:2011-07-27 02:16:42
【问题描述】:

首先,我想说我已经搜索了这个问题的答案,但没有得到合适的解决方案。所以我决定把它贴在这里。

我有一个对象的 ArrayList (ArrayList(Provider))。 Provider 对象有名字、姓氏、NPI 编号、列表(我没有列出所有字段)。

Provider {

        private long providerId;
        private String npiNumber;
        private PersonName providerName;
        private List<Address> providerAddresses;

        }

现在我想根据这些属性(名字、姓氏、NPI、地址)查找 ArrayList 是否有重复项。每个提供者将有 2 个地址。我们遇到的问题是提供者对象是从 XSD 生成的,无法修改。所以我不能覆盖equals和hashcode方法。所以 Hashset(list) 不起作用。

那么检查 ArrayList 是否有重复对象的最佳方法是什么。请告诉我

谢谢

哈里什

【问题讨论】:

    标签: java object arraylist duplicates


    【解决方案1】:

    如果您想知道重复项是什么,可以使用自定义 Comparator&lt;Provider&gt; 或 TreeMap 创建 TreeSet&lt;Provider&gt;

    【讨论】:

      【解决方案2】:

      您可以通过包装地址来使用 HashSet(list) 技巧。

      class AddressWrapper {
          Address address;
          public boolean equals(Object o) {
              if(!(o instanceof AddressWrapper)) return false;
              AddressWrapper aw = (AddressWrapper)o;
              Address a = aw.address;
              return a.street.equals(address.street)
                  && a.otherValues.equals(address.otherValues); // fill these in
      
          }
          public int hashCode() {
              int hash = address.street.hashCode();
              hash = hash * 31 + address.otherValues;
              // others
              return hash;
      
          }
      
      }
      

      【讨论】:

      • 谢谢发光编码器。我创建了一个 ProviderWrapper 并能够覆盖 equals 方法,它适用于 Provider 对象中的字符串和 int 字段。但问题是 Provider 有一个字段:List
        。我已经为地址对象创建了一个 AddressWrapper,但是如何在 Provider 下使用 AddressWrapper 而不是 Address 对象。希望你能理解我的问题
      • 在您的ProviderWrapper.equals() 方法中,您可以从您的List&lt;Address&gt; 创建一个List&lt;AddressWrapper&gt;
      【解决方案3】:

      您是否尝试过 apache commons CompareToBuilder?它使用反射来比较对象,甚至可以处理私有成员。我相信它也可以进行深度比较,因此它应该能够跟随您的 List 元素并比较它们。但是,如果不能,您可能必须单独比较它们。

      无论如何,您应该能够使用 TreeSet 和自定义比较器的某种组合。 请注意,此代码未经测试,可能不是最高效的方式,但它应该可以用最少的代码完成工作。

              class DupeComparator implements Comparator{
      
                  @Override
                  public int compare(Object o1, Object o2){
      
                      // Might have to roll your own compare here if CompareToBuilder doesn't do
                      // a deep compare of your List<Address> Fields
                      return CompareToBuilder.reflectionCompare(o1, o2);
                  }           
              }
      
              TreeSet set = new TreeSet(new DupeComparator());
      
              // this should give you a tree set without duplicates
              set.addAll(providerList); 
      
              // If you need to know which elements are dupilicates you'd
              // probably have to iterate your list           
              for(Provider p : providerList){
                  if(!set.contains(p))
                      set.add(p);
                  else
                      System.out.printn(p + " is a duplicate");
              }
      
      
      EDIT: Changed from EqualsBuilder to CompareToBuilder which makes more sense in this case.
      

      【讨论】:

        【解决方案4】:

        这里是如何使用 JAXB 调整 equals 和 hashCode 方法的链接:

        http://confluence.highsource.org/display/J2B/JAXB2+Basics+Plugins

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-08-13
          • 2012-03-08
          • 2022-01-07
          • 1970-01-01
          • 2016-04-17
          • 2018-12-18
          • 1970-01-01
          • 2021-08-26
          相关资源
          最近更新 更多