【问题标题】:Best way to compare Two Lists of Objects in Java比较Java中两个对象列表的最佳方法
【发布时间】:2015-11-14 01:27:54
【问题描述】:

我有两个对象列表。

public class CustomObj {
    Long key1;
    Integer key2;
    Integer key3;
    Integer key4;
    Integer key5;
    BigDecimal value1
    BigDecimal value2
    BigDecimal value3
    BigDecimal value4
    BigDecimal value5; }

public class CustomKey {
    Long key1;
    Integer key2;
    Integer key3;
    Integer key4;
    Integer key5; }

对象没有唯一标识符,但对象中的 5 个字段 key1 到 key5 构成对象的唯一键。我必须比较这两个对象列表。仅当由 key1-key5 字段组成的唯一键在两个对象中相同时,我才必须比较对象内部的值。

目前我正在创建两个代表两个列表的 HashMap。

Map<CustomKey, CustomObj>

然后,我遍历第一个 hashmap,对于每个键,我检查该键是否存在于其他 hashmap 中,如果存在,我从其他 hashmap 中获取对象,然后比较这两个对象。

有没有更好的方法?

【问题讨论】:

  • 你能展示你如何比较它们的代码吗?然后我们可以告诉您是否可以。
  • 你必须重写 equals/hashcode 方法
  • 假设我有两个地图,即从对象列表生成的 objMap1、objMap2。 ` for(Map.Entry entry : objMap1.entrySet()) { CustomKey key = entry.getKey(); CustomObject a = entry.getValue(); CustomObject b = objMap2.get(key); } ` 因为我现在有两个具有相同键的对象,所以我可以比较这些对象的值。
  • 只有当两个对象中由 key1-key5 字段组成的唯一键相同时,我才必须比较对象内部的值是什么意思?听起来您无论如何都需要比较所有字段以确定两个对象是否相等。

标签: java list dictionary hashmap


【解决方案1】:

根据前五个键覆盖 equals 和 hashcode 方法。 然后你可以使用 equals 方法来比较对象和 使用 Collections 批量操作,如 retainAll 等。

【讨论】:

    【解决方案2】:

    您可以覆盖 CustomObj 的 Equals 和 HashCode。 然后使用 Contains() 测试唯一性。

    【讨论】:

      【解决方案3】:

      我推荐使用Objects.equals()Objects.hash()来实现相等性检查和哈希码计算。它们是 null 安全的,并且易于编写和理解:

      public class CustomKey {
          Long key1;
          Integer key2;
          Integer key3;
          Integer key4;
          Integer key5; 
      
          @Override
          public boolean equals(Object o) {
              if (o == this) return true;
              if (!(o instanceof CustomKey)) return false;
              CustomKey k = (CustomKey) o;
              return Objects.equals(key1, k.key1)
                  && Objects.equals(key2, k.key2)
                  && Objects.equals(key3, k.key3)
                  && Objects.equals(key4, k.key4)
                  && Objects.equals(key5, k.key5);
          }    
      
          @Override
          public int hashCode() {
              return Objects.hash(key1, key2, key3, key4, key5);
          }
      }
      

      CustomObj类似。

      实现这些方法后,您可以安全地在哈希集合中使用这些对象。

      【讨论】:

        【解决方案4】:

        希望这会对你有所帮助,这是你的课程:

        1. Class CustomObj 覆盖对象的equal 方法,在实现中我将CustomObj 类的属性与CustomKey 进行比较

        自定义对象:

        public class CustomObj {
            Long key1;
            Integer key2;
            Integer key3;
            Integer key4;
            Integer key5;
            BigDecimal value1;
            BigDecimal value2;
            BigDecimal value3;
            BigDecimal value4;
            BigDecimal value5;
        
            public CustomObj(Long k1, Integer k2, Integer k3, Integer k4, Integer k5){
                this.key1 = k1;
                this.key2 = k2;
                this.key3 = k3;
                this.key4 = k4;
                this.key5 = k5;
            }
            @Override
            public int hashCode() {
                final int prime = 31;
                int result = 1;
                result = prime * result + ((key1 == null) ? 0 : key1.hashCode());
                result = prime * result + ((key2 == null) ? 0 : key2.hashCode());
                result = prime * result + ((key3 == null) ? 0 : key3.hashCode());
                result = prime * result + ((key4 == null) ? 0 : key4.hashCode());
                result = prime * result + ((key5 == null) ? 0 : key5.hashCode());
                return result;
            }
            @Override
            public boolean equals(Object obj) {
                if (this == obj)
                    return true;
                if (obj == null)
                    return false;
                CustomKey other = (CustomKey) obj;
                if (key1 == null) {
                    if (other.key1 != null)
                        return false;
                } else if (!key1.equals(other.key1))
                    return false;
                if (key2 == null) {
                    if (other.key2 != null)
                        return false;
                } else if (!key2.equals(other.key2))
                    return false;
                if (key3 == null) {
                    if (other.key3 != null)
                        return false;
                } else if (!key3.equals(other.key3))
                    return false;
                if (key4 == null) {
                    if (other.key4 != null)
                        return false;
                } else if (!key4.equals(other.key4))
                    return false;
                if (key5 == null) {
                    if (other.key5 != null)
                        return false;
                } else if (!key5.equals(other.key5))
                    return false;
                return true;
            }
        
        }
        

        自定义密钥:

        public class CustomKey {
            Long key1;
            Integer key2;
            Integer key3;
            Integer key4;
            Integer key5;
        
            public CustomKey(Long k1, Integer k2, Integer k3, Integer k4, Integer k5){
                this.key1 = k1;
                this.key2 = k2;
                this.key3 = k3;
                this.key4 = k4;
                this.key5 = k5;
            }
        }
        
        To Test it:
        
        
        
        public static void main(String[] args) {
                CustomObj customObj = new CustomObj(123L, 11, 34, 45, 99);
                CustomKey customKey = new CustomKey(123L, 11, 34, 45, 99);
                CustomKey customKey2 = new CustomKey(124L, 12, 34, 45, 99);
        
                System.out.println(customObj.equals(customKey));// This will return true since the key is same
                System.out.println(customObj.equals(customKey2));// This will return false since the key is same
            }
        

        【讨论】:

        • 不错的尝试,但您这样做的方式过于复杂。而且您的代码可能会导致ClassCastException,因为您不执行instanceof 检查。
        猜你喜欢
        • 2012-05-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-01
        相关资源
        最近更新 更多