Wei Shi
Wei Shi

Reputation: 5055

implement 2 flavors of Equals method for a class in Java

public class Foo{
    private final int A;
    private final int B;
    public boolean equals(Object o){
        //type check omitted
        return A==o.A && B==o.B;
    }

}

I want to have another .equals() method like this

public boolean equals(Object o){
    return A==o.A;
}

The Foo object is first created with A,B field, then I want to send them off to a Set<E> that used the 2nd equals() method to only compares field A.

I know I can create new objects that only have A field, but overhead would be big. Any advice?

Upvotes: 8

Views: 1346

Answers (4)

gatkin
gatkin

Reputation: 1912

If the alternate equals method is just for this particular set, I'd suggested using TreeSet (or another SortedSet) instead of HashSet so that you can use the TreeSet(Comparator) constructor.

Upvotes: 0

Mark Peters
Mark Peters

Reputation: 81074

Using composition, you could create a FooWrapper class that provides a custom implementation of equals and add that to the set instead:

public class FooWrapper {
    public final Foo foo; //constructor omitted

    public boolean equals(Object other) {
         //type check omitted here too
         return foo.A == other.foo.A;
    }

    //hashCode omitted, but you need that too
}

Unfortunately with the Java Collections API there is no way to tell a collection to use a custom equals computation other than the method above or subclassing and overriding equals().

Edit:

It strikes me that you might instead be able to make use of a Map<Integer, Foo> instead, using foo.A as the key and foo as the value (and thus restricting it to unique values of A). I couldn't tell you whether that's suitable without more context though.

Upvotes: 7

Puce
Puce

Reputation: 38132

I have written a matcher framework for this:

The base interface is Matcher (similar to Comparable): http://softsmithy.sourceforge.net/lib/docs/api/org/softsmithy/lib/util/Matcher.html

MatchableObject is a class, which applies a matching strategy to an Object: http://softsmithy.sourceforge.net/lib/docs/api/org/softsmithy/lib/util/MatchableObject.html

Matchers is a utility class to wrap/ unwrap MatchableObjects: http://softsmithy.sourceforge.net/lib/docs/api/org/softsmithy/lib/util/Matchers.html

The library is Open Source. Maybe you find it useful.

Homepage:

http://www.softsmithy.org

Download:

http://sourceforge.net/projects/softsmithy/files/softsmithy/

Maven:

<dependency>  
    <groupid>org.softsmithy.lib</groupid>  
    <artifactid>lib-core</artifactid>  
    <version>0.1</version>  
</dependency>  

Upvotes: 0

planetjones
planetjones

Reputation: 12633

There can only be one implementation of equals per Object as it's overriding the inherited method from java.lang.Object. I think you need to decide on what equality means for Foo - is A the only significant field; if so just use that. Your alternative is to wrap Foo and provide a custom equals method for the WrappedFoo Object. You can then store WrappedFoo in the Set.

From a design perspective it sounds like there should be two Objects here - one which is a value class for A and one which is a value class for B. You can use composition if you need a single Object to represent A and B.

Upvotes: 0

Related Questions