Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing meaningful equals method for non-static inner classes [duplicate]

I am currently wondering if there is a good way of implementing an equals method for a non-static inner class in Java. I basically a class Foo with an inner-class Bar like this:

public class Foo {

  private final String foo; // constructor omitted

  public /* non-static */ class Bar {

    private final String bar; // constructor omitted

    @Override
    public boolean equals(Object other) {
      return other != null && other.getClass() == getClass()
        && ((Bar) other).bar.equals(this.bar)
        && Foo.this.equals(Foo.((Bar) other)); // Will, of course, not compile.
    }
  }

  @Override
  public boolean equals(Object other) {
    return other != null && other.getClass() == getClass()
      && ((Foo) other).foo.equals(foo);
  }
}

My classes are a lot more complex in reality and I want to reuse the Foo#equals method from within Bar#equals in order to save me a lot of code. I am now considering to make the "inner-class-relationship" explicit in order to being able to refer to the "outer" class. However, then I have to add accessor methods manually and I want to avoid this. I cannot get rid of the feeling that there should be a Java approach of doing this.

like image 427
Rafael Winterhalter Avatar asked Nov 11 '22 11:11

Rafael Winterhalter


1 Answers

Yes, this is possible. This is often done when you need to pass around "Key" objects that represent a unique identifier for some set of data but do not either have the data or want to transport it.

class SomeData {
    private String data;
    public static class Key {
        private final int firstId;
        private final int secondId; 

        public Key(int firstId, int secondId) {
            this.firstId = firstId;
            this.secondId = secondId;
        }

        public boolean equals(Object x) {
            if(!(x instanceof Key))
                return false;
            Key key = ((Key)x);

            return this.firstId == key.firstId 
            && this.secondId == key.secondId;

        }

        // implement hashCode as well
    }
}

In the example above the inner class is static but that doesn't really matter. The only reason I set it that way is so that exterior classes could construct it. Make sure when you are overriding the .equals that you also get the .hashCode. They should change with each other.

like image 68
Chuck Lowery Avatar answered Nov 14 '22 21:11

Chuck Lowery