user1119859
user1119859

Reputation: 719

How to define hashcode and equals if your object only consists of interfaces?

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

Answers (4)

user2579273
user2579273

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

Boann
Boann

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

loadP
loadP

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

Alex Kolokolov
Alex Kolokolov

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

Related Questions