Bober02
Bober02

Reputation: 15331

Java - equals and hashcode

I am thinking of using a Set of BusinessObjects in Java. My intention is, that in each set there should be only ONE instance of each business object, but one business object can be shared across many sets. So, as an example:

BO1 - instance of BusinessObject1
BO11 - instance of BusinessObject1
BO2 - instance of BusinessObject2

this is correct

[BO1, BO2] or [BO1]

but this isn't [BO1, BO11]

Since I wanted to make sure this is enforced, I was thinking of specifying an AbstractBusinessObject like this:

public abstract class AbstractBusinessObject {

    @Override
    public int hashCode() {
        return this.getClass().getName().hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj != null)
            return this.getClass() == obj.getClass();
        return false;
    }
}

Do you think that is a good idea?

Upvotes: 1

Views: 352

Answers (4)

coyotesqrl
coyotesqrl

Reputation: 162

If for some reason you can't follow AmitD's advice and use Enums, then instead of Sets you could use Maps keyed on a marker interface.

I have no idea what problem this would be solving, but...

  1. Create a new Marker interface
  2. Have each of your Business Object classes implement it
  3. In each place where you want a collection as you've described it, use

    Map<Class<? extends Marker>, Marker> soloBOMap = // whatever concrete map;
    soloBOMap.put(bo.getClass(), bo);
    

It's weird; of that I'm sure.

Upvotes: 0

Amit Deshpande
Amit Deshpande

Reputation: 19185

Why not simply use Enums? You can use Enum of business objects and EnumSet of Business Objects.

public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
    THURSDAY, FRIDAY, SATURDAY;
    static final EnumSet<Day> weekend = EnumSet.of(SATURDAY,SUNDAY);
}

Tutorial here

Now if your business object are not designed for above purpose then just implement equals and hashcode in a normal way. HashSet add method will anyway ignore duplicates.

This link discusses about equals and hashcode contract.

For Business objects general rule is equals and hashcode needs to be implemented using your business object PK.

Like For Employee object employee number can be considered as business key and pk can be different so equals and hashcode should based on employee number.

Upvotes: 4

Jakub Zaverka
Jakub Zaverka

Reputation: 8874

Throw all business objects into a HashSet. You cannot have duplicates in a HashSet (by the equals method), so if you throw B1, B11 and B2 into a HashSet, it will contain B1 and B2.

You should override the equals and hashCode methods in the BusinessObject to work with those attributes that make a BusinessObject unique.

Upvotes: 2

matt b
matt b

Reputation: 139921

No, this is a bad idea. This does not actually prevent different sections of your code from doing

BusinessObject bo1 = new BusinessObject();
bo1.setId(1);
bo1.setName("foo");

BusinessObject bo1copy = new BusinessObject();
bo1copy.setId(1);
bo1copy.setName("bar");

And thus having two copies of the same "business object" with different field values.

Your equals() implementation would also treat all instances of BusinessObject as having the same value (bo1.equals(bo1copy) == true in the above code), which will mess up using it in any sort of collection.

If you need to control the number of instances of a certain type instantiated in your program, then simply only instantiate one instance of the object.

Upvotes: 3

Related Questions