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