Java 具有两个不同字段的类的哈希代码

Java 具有两个不同字段的类的哈希代码,java,hashtable,hashcode,Java,Hashtable,Hashcode,我似乎找不到解决这个问题的办法: a、 示例1.1.1.1 a、 示例1.2.1.1 其中第一列是主机名,第二列是ip。 这两个信息用于组成类Router.java的对象。我想使用Router.java的对象作为Hashmap的键,使用Boolean作为值,即Hashmap 我希望使用“.containsKey”方法的方式是,它检查其中一个字段(无论是hostname还是ip)是否相同,然后它应该返回true。同样在这种情况下,我希望将hashmap中的Router.javaaskey对象对应的

我似乎找不到解决这个问题的办法:
a、 示例1.1.1.1
a、 示例1.2.1.1
其中第一列是主机名,第二列是ip。 这两个信息用于组成类
Router.java
的对象。我想使用
Router.java
的对象作为Hashmap的键,使用
Boolean
作为值,即
Hashmap

我希望使用“.containsKey”方法的方式是,它检查其中一个字段(无论是
hostname
还是
ip
)是否相同,然后它应该返回true。同样在这种情况下,我希望将hashmap中的
Router.java
askey对象对应的值设置为true

我的问题是,我不知道如何编写hash方法,以便两个对象具有相同的hash并转到.equals()


我觉得在错误的基础上找到临时解决问题的方法是非常糟糕的做法。equals方法执行错误。它与合同相矛盾,因此代码以后可能会有很多问题

假设有3个
Router
对象

  • Object1:
    routerA
    的主机名为a.abc,ip=107.108.109.100

  • Object2:
    routerB
    的主机名为a.abc,ip=107.108.109.200

  • Object3:
    routerC
    的主机名为b.abc,ip=107.108.109.100

    routerA.equals(routerB);//计算结果为TRUE

    routerA.equals(routerC);//计算结果为TRUE

    routerB.equals(routerC);//应评估为真,但评估为假,根据equals合同,这是错误的

  • 参考:

  • 它是自反的:对于任何非空参考值x,x.equals(x)应该返回true

  • 它是对称的:对于任何非空的引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)才应返回true

  • 它是可传递的:对于任何非空引用值x、y和z,如果x.equals(y)返回true,y.equals(z)返回true,那么x.equals(z)应该返回true。

  • 它是一致的:对于任何非空的引用值x和y,x.equals(y)的多次调用始终返回true或false,前提是没有修改对象上equals比较中使用的信息

  • 对于任何非空引用值x,x.equals(null)应返回false

  • 在收集对象中使用
    Router
    的对象可能会有问题,并且在排序时可能会得到意外的结果。此外,尽管代码的后续工作将面临巨大的维护问题,但任何查看代码的人都很难理解逻辑(在本例中,这实际上是错误的)。一个新加入这样一个代码库的项目的人会做噩梦

    重构是一种很好的习惯,我们都会犯错误,但我们更好地学习、认识和纠正错误,而不是继续前进

    我希望您纠正您的逻辑,并按照为这些方法设置的合同实施
    equals
    hashcode
    。祝你好运,干杯

    [更新]
    我还看到了@RustyX在下面给出的答案,()在您的例子中,您可以使用2个hashmap,一个以IP为键,布尔值为值,另一个以主机名为键,布尔值为值。在检查路由器时,您可以检查其IP是否以IP作为密钥存在于Hashmap中,或者主机名是否是以主机名作为密钥的Preent jn Hashmap。在放置需要查看的结果时,不要在两个贴图中放置冲突的值。通过一些仔细编写的方法和检查,希望您能够找到问题的解决方案。注意,正如RustyX im所提到的,在这种情况下,您可能不需要实现equals和hashcode来至少处理这种情况

    我觉得在错误的基础上找到临时解决问题的方法是非常糟糕的做法。equals方法执行错误。它与合同相矛盾,因此代码以后可能会有很多问题

    假设有3个
    Router
    对象

  • Object1:
    routerA
    的主机名为a.abc,ip=107.108.109.100

  • Object2:
    routerB
    的主机名为a.abc,ip=107.108.109.200

  • Object3:
    routerC
    的主机名为b.abc,ip=107.108.109.100

    routerA.equals(routerB);//计算结果为TRUE

    routerA.equals(routerC);//计算结果为TRUE

    routerB.equals(routerC);//应评估为真,但评估为假,根据equals合同,这是错误的

  • 参考:

  • 它是自反的:对于任何非空参考值x,x.equals(x)应该返回true

  • 它是对称的:对于任何非空的引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)才应返回true

  • 它是可传递的:对于任何非空引用值x、y和z,如果x.equals(y)返回true,y.equals(z)返回true,那么x.equals(z)应该返回true。

  • 它是一致的:对于任何非空的引用值x和y,x.equals(y)的多次调用始终返回true或false,前提是没有修改对象上equals比较中使用的信息

  • 对于任何非空引用值x,x.equals(null)应返回false

  • 在收集对象中使用
    Router
    的对象可能会有问题,并且在排序时可能会得到意外的结果。此外,尽管代码的后续工作将面临巨大的维护问题,但任何查看代码的人都很难理解逻辑(在本例中,这实际上是错误的)。一个新加入这样一个代码库的项目的人会做噩梦

    重构是一种很好的习惯,我们都会犯错误,但我们学得更好,真的
     import java.util.Objects;
    
       `enter code here`public class Router {
    
    
       String hostname;
       String ip_address;
       String patched;
        String os_version;
        String notes;
    
        public Router(String hostname,String ip_address,String patched,String     os_version,String notes)
       {
    
        this.hostname = hostname;
        this.ip_address = ip_address;
        this.patched = patched;
        this.os_version = os_version;
        this.notes = notes;
    
       }
    
    
       @Override
    
       public boolean equals(Object o) {
    
        if (o == this) 
            return true;
        if (!(o instanceof Router)) {
            return false;
        }
    
    
        Router r = (Router) o;
    
        return r.hostname.equals(hostname) ||
                r.ip_address.equals(ip_address) ;
    
       }
    
       @Override
       public int hashCode() {
    
    
    
    
    
    
       }
    
    
    
       }