Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/373.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如果对象只包含接口,如何定义hashcode和equals?_Java_Interface_Hashcode - Fatal编程技术网

Java 如果对象只包含接口,如何定义hashcode和equals?

Java 如果对象只包含接口,如何定义hashcode和equals?,java,interface,hashcode,Java,Interface,Hashcode,让我们假设我有一个小小的(java)类,它只是由3个接口对象组成。这三个对象一起构成贴图的键值。现在我的问题是:如何为该类定义equals和hashcode?我的意思是,这个类的所有成员都只是接口,没有实现任何东西 例如: class SomeKey { public SomeKey(SomeWeiredInterface1 a, SomeWeiredInterface2 b, SomeWeiredInterface3 c){ .... } } 最直接的方法是: publi

让我们假设我有一个小小的(java)类,它只是由3个接口对象组成。这三个对象一起构成贴图的键值。现在我的问题是:如何为该类定义equals和hashcode?我的意思是,这个类的所有成员都只是接口,没有实现任何东西

例如:

class SomeKey {
  public SomeKey(SomeWeiredInterface1 a, SomeWeiredInterface2 b,     SomeWeiredInterface3 c){
    ....
}
}
最直接的方法是:

public boolean equals(Object other){
SomeKey otherKey = (SomeKey)other;  

return a.equals.otherKey.a && b.equals.otherKey.b && c.equals.otherKey.c;
}
对我来说,这似乎根本不可能,或者至少我必须自己编写这些方法,因为我不能使用(或委托)这些接口实现的任何hashcode或equals方法

谢谢你的提示! Thorsten

以下是IDE自动生成的equals()和hashCode()方法:

public class SimpleClass {
private SimpleFirstInterface firstField;
private SimpleSecondInterface secondField;

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    SimpleClass that = (SimpleClass) o;

    if (firstField != null ? !firstField.equals(that.firstField) : that.firstField != null) return false;
    return secondField != null ? secondField.equals(that.secondField) : that.secondField == null;

}

@Override
public int hashCode() {
    int result = firstField != null ? firstField.hashCode() : 0;
    result = 31 * result + (secondField != null ? secondField.hashCode() : 0);
    return result;
}
}


这两个方法在它们内部使用接口实现的equals()和hashCode()方法(如果有)。如果没有,则将使用对象的equals()和hashCode()的标准实现。

所有接口都隐式声明
对象
类中的所有公共方法(请参阅)。您可以调用接口类型的
equals
hashCode
方法,它将在实现接口的任何具体类中调用重写的方法,或者它将调用从
对象继承的那些方法的默认实现

您可以以相同的方式编写
SomeKey
equals
hashCode
方法,而不考虑字段类型是类还是接口:

@Override
public boolean equals(Object o) {
    if (o == this) return true;
    if (!(o instanceof SomeKey)) return false;
    SomeKey other = (SomeKey)o;
    return a.equals(other.a) && b.equals(other.b) && c.equals(other.c);
}

@Override
public int hashCode() {
    return java.util.Objects.hash(a.hashCode(), b.hashCode(), c.hashCode());
}

可能类似于使用Comparable接口覆盖hashcode()、equals()和compareTo()方法。尝试使用其他接口。 当然,我没有读上面的答案,也没有读例子

  private static class SomeString implements Comparable<SomeString> {
   private final String s;
   SomeString(final String s) {
   this.s = s;
  }

@Override
public int compareTo(final SomeString o) {
 return s.compareTo(o.s);
}

您可以使用(委托)实现类的equals和hashcode方法,但是是的,您不能依赖它们

实现类可能包含hashcode&equals,它不会为同一对象生成唯一的结果,也不会为同一对象生成不同的hashcode

我相信这3个接口是而不是标记接口,并且有一些方法返回实现类的成员变量的状态。 如果上述情况属实,那么您可以在自己的hashcode()&equals实现中使用状态

见示例:

Interface A{
   getValue();
}

Interface B{
   getData();
}

class AImpl implements A{
      private String value;

      public String getValue(){
            return value;
      }
}
class BImpl implements B{
      private int data;

      public int getData{
            return data;
      }
}

class SomeKey{

   private A value;
   private B data;

    //constructor
    public SomeKey(A value, B data){
         this.value = value;
         this.data = data;      
    }

 @Override
 public int hashcode(){
     int result = 1;
     result = 29 * result + value.hashcode();
     result = result + data.hashcode();
     return result;
 }
 //similarly override equals
}    

为什么不呢?您可以在这些对象上调用
equals
hashCode
。好的,那么equals或hashCode是在实现接口的对象上执行的吗?这是有道理的;-)但另一方面,equals和hashCode不是接口定义的一部分?!是的,是的。那又怎么样?您仍然可以在作为接口键入的对象上调用
equals
hashCode
,但为什么?我可以在接口对象上调用equals和hashCode吗,因为这两个方法都是object.class“basic”方法的一部分?如果在实现类的接口中有更具体的hashCode或equals实现,则调用equals或hashCode方法,否则调用Object.class?Yes和Yes。您试过了吗?所以,如果SimpleFirstInterfaceImpl类实现了SimpleFirstInterfaceImpl,那么将调用SimpleFirstInterfaceImpl中的equals和hashCode。如果SimpleFirstInterfaceImpl没有实现这些函数,则会调用Object中的函数?是的。精确地但是,如果您希望HashMap有效地工作,您应该对这些方法进行定性实现,而不是依赖于来自对象的方法。
Interface A{
   getValue();
}

Interface B{
   getData();
}

class AImpl implements A{
      private String value;

      public String getValue(){
            return value;
      }
}
class BImpl implements B{
      private int data;

      public int getData{
            return data;
      }
}

class SomeKey{

   private A value;
   private B data;

    //constructor
    public SomeKey(A value, B data){
         this.value = value;
         this.data = data;      
    }

 @Override
 public int hashcode(){
     int result = 1;
     result = 29 * result + value.hashcode();
     result = result + data.hashcode();
     return result;
 }
 //similarly override equals
}