2014-07-23 1 views
0

J'ai des classes comme ci-dessousRedéfinition égale pour CopyOnWriteArraySet.add et enlever

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 

Je veux créer une file d'attente globale où si l'objet C existe dans la file d'attente B devraient être autorisés à ajouter, mais pas dans l'autre sens autour. Donc avant # 1, je fais une boucle sur les éléments à l'intérieur de l'ensemble en faisant element.equals (B) avec add on false.

Mais 1 appelle B.equals (C), qui retourne vrai et si mySet n'a qu'un seul objet C après cette ligne

2 est à nouveau B.equals appellent (C), qui retourne vrai et le retrait l'objet existant C. Ne devrait-il pas être C.equals (B) dans ce cas? Je m'attends à cette ligne comme aucune action

Est-ce une mauvaise utilisation de CopyOnWriteArraySet?

Merci pour la recherche

+2

Bien que votre méthode 'equals' ne soit pas correctement implémentée, toutes sortes de choses dans l'API Collections qui reposent sur' equals' vont se comporter de façon inattendue. – markspace

+3

égal doit être associatif comme documenté dans Object.equals() c'est-à-dire a.equals (b) == b.equals (a) sinon vous aurez de la confusion. –

+1

De plus, 'Object.equals (null)' devrait toujours retourner 'false'. – yshavit

Répondre

0

HashSet est la collection correcte pour mon cas. Il n'appellera pas d'égal pendant l'ajout d'éléments, à moins que hashCode ne corresponde. De cette façon, je peux toujours utiliser mes méthodes égales pour mon but spécifique.

2

Il est un comportement correct, il trouve l'élément qui est equal() retire donc premier élément

Supprime l'élément spécifié de cet ensemble si elle est présente. Plus formellement, supprime un élément e tel que (o==null ? e==null : o.equals(e)), si cet ensemble contient un tel élément. Renvoie true si cet ensemble contient l'élément (ou, de manière équivalente, si cet ensemble a changé à la suite de l'appel). (Cet ensemble ne contiendra pas l'élément une fois l'appel retourne.) ...

+0

True. Mais mon intention est d'autoriser l'ajout de B quand C est dans l'ensemble et non l'inverse. Aussi je veux enlever B ou C avec enlever (B) et enlever (C) et pas au hasard. Ma question est si ce copyonwritearrayset est le bon cours de collection pour ma tâche? – yalkris

+0

'Set' n'autorise pas la duplication, il vérifie la duplication basée sur' equals() 'et (' hashcode() 'dans le cas de la structure de données basée sur le hachage), si vous voulez qu'il permute en double' List' –

+0

CopyOnWriteArrayList mais le problème est quand j'appelle ajouter (C) et ajouter (B) la liste a deux éléments et quand je fais un retrait (B) il supprime C à la place. – yalkris