Reputation: 719
let's assume I have a little (java) class that simply consist of 3 interface objects. These 3 objects together make up a key value for a map. Now my quesion is: how to define equals and hashcode for that class ? I mean, all members of that class are just interfaces who doesn't implement anything ?
Example:
class SomeKey {
public SomeKey(SomeWeiredInterface1 a, SomeWeiredInterface2 b, SomeWeiredInterface3 c){
....
}
}
The most straight forward way would be:
public boolean equals(Object other){
SomeKey otherKey = (SomeKey)other;
return a.equals.otherKey.a && b.equals.otherKey.b && c.equals.otherKey.c;
}
To me it looks like it's simply not possible, or at least I have to write these methods on my own, because I can't use (or delegate) any hashcode or equals methods of the implementation of these interfaces ?
Thanks for any hints! Thorsten
Upvotes: 1
Views: 82
Reputation: 91
You can use(delegate) equals and hashcode methods of implementation classes but yes, you can't rely on them.
The implementation classes may contain hashcode & equals which doesn't produce unique result for the same object or different hashcode for the same object.
I believe these 3 interfaces are not marker interface and has some methods which returns the state of the member variables of the implementation class. If the above is true, then you can use the state in your own hashcode() & equals implementation.
See example:
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
}
Upvotes: 0
Reputation: 50041
All interfaces implicitly declare all the public methods from the Object
class (see JLS § 9.2). You can call the equals
and hashCode
methods of your interface types, and it will call the overridden methods in whatever concrete class implements the interface, or it will call the default implementations of those methods inherited from Object
.
You can write the equals
and hashCode
methods of SomeKey
the same way, without regard for whether the field types are classes or interfaces:
@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());
}
Upvotes: 2
Reputation: 404
Perhaps something like overwriting the methods hashcode(), equals() and compareTo(), using the Comparable Interface. To try with other Interfaces. I didn't read the answers above, of course well examples.
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);
}
}
@Override
public boolean equals(final Object o) {
if(o == null) return false;
if(this == o) return true;
if(this.getClass() != o.getClass()) return false;
final SomeString o1 = (SomeString) o;
return compareTo(o1) == 0;
}
@Override
public int hashCode() {
return s.hashCode();
}
Upvotes: -1
Reputation: 143
These are the equals() and hashCode() methods generated automaticlly by my IDE:
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;
}
}
These two methods are using inside of them the equals() and hashCode() methods of the interfaces implementations if they are provided there. If not, then standard implementation of Object's equals() and hashCode() will be used.
Upvotes: 1