Overriding equals for CopyOnWriteArraySet.add and remove
Asked Answered
G

2

0

I have classes like below

class A {
    @Override
    public boolean equals(Object other) { return true }
}

Class B extends A {
}

Class C extends A {
    @Override
    public boolean equals(Object other) { if ((other != null) || (other instanceOf B)) return false; }
}

In my main() I have this following code
Set<A> mySet = new CopyOnWriteArraySet<A>();

mySet.add(C);
I want mySet to contain C at this point

mySet.add(B); // #1
I want mySet to contain C & B at this point

mySet.remove(B); // #2
I want mySet to contain C at this point

I want to create a global queue where if object C exists in the queue B should be allowed to be added but not the other way around. So before #1 I am looping through the elements inside the set doing element.equals(B) with add on false.

But 1 is calling B.equals(C) which is returning true and so mySet has only one C object after this line

2 is again calling B.equals(C) which is returning true and removing the existing object C. Shouldn't it be C.equals(B) in this case? I am expecting this line as no-action

Is this some wrong use of CopyOnWriteArraySet?

Thanks for looking

Guyon answered 23/7, 2014 at 20:42 Comment(5)
Well your equals method is implemented incorrectly, so all sorts of things in the Collections API which rely on equals are going to behave unexpectedly.Semiology
equals must be associative as documented in Object.equals() i.e. a.equals(b) == b.equals(a) otherwise you will get confusion.Detestation
Also, Object.equals(null) should always return false.Wivern
Let me rephrase my question on what I am intending to do in my caseGuyon
@PeterLawrey That's symmetric, not associativeThrive
G
0

HashSet is the correct collection for my case. It won't call equals while adding elements unless there is hashCode match. That way I can still use my equals methods for my specific purpose.

Guyon answered 23/7, 2014 at 21:35 Comment(0)
C
2

It is correct behavior it finds the element which is equal() so it removes first element

Removes the specified element from this set if it is present. More formally, removes an element e such that (o==null ? e==null : o.equals(e)), if this set contains such an element. Returns true if this set contained the element (or equivalently, if this set changed as a result of the call). (This set will not contain the element once the call returns.) ...

Callipygian answered 23/7, 2014 at 20:43 Comment(6)
True. But my intention is to allow B to be added when C is in the set and not the other way around. Also I want to remove B or C with remove(B) and remove(C) and not randomly. My question is if this copyonwritearrayset is the right collection class for my task?Guyon
Set doesn't allow duplicate, it checks duplicate based on equals() and (hashcode() in case of hash based datastructure), if you want it to allow duplicate switch to ListCallipygian
I used CopyOnWriteArrayList but the problem is when I call add(C) and add(B) the list has two elements and when I do a remove(B) it is removing C instead.Guyon
because B equals C I doubt it even added CCallipygian
List won't call equals while adding elementsGuyon
HashSet worked in my case. It won't call equals unless the hashCode matches.Guyon
G
0

HashSet is the correct collection for my case. It won't call equals while adding elements unless there is hashCode match. That way I can still use my equals methods for my specific purpose.

Guyon answered 23/7, 2014 at 21:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.