IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Collection et Stream Java Discussion :

Collection.retainAll: basé sur quoi ?


Sujet :

Collection et Stream Java

  1. #1
    Membre confirmé
    Inscrit en
    Décembre 2003
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 126
    Par défaut Collection.retainAll: basé sur quoi ?
    Bonjour,

    j'ai un soucis avec .retainAll... l'API n'est pas claire à mon avis sur le sujet.

    Ca réalise l'intersection de deux collections oui mais comment ? Le .equals() sera joué pour savoir si deux item sont identiques dans les deux collections, ou bien est-ce 2 références du même objet seulement ? (Dans ce cas-là a sert pas tous les jours).

    Merci.

    Gal'

  2. #2
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    l'api est assez clair, elle dit que çà retire tout ce qui n'est pas contenu dans l'autre collection. Et en meme temps, l'api Collection défini aussi la notion de contains() et précise que, pour çà, elle utilise equals()

  3. #3
    Membre confirmé
    Inscrit en
    Décembre 2003
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 126
    Par défaut
    oki merci.

  4. #4
    Membre confirmé
    Inscrit en
    Décembre 2003
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 126
    Par défaut
    Non en fait j'ai encore une pb... j'ai une classe ou je redefinis bien public boolean equals(Object o), mais le retainAll me renvoit un set vide.

    Mais avec une implémentation maison, ça marche:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    	private Set<T> getIntersection(Set<T> c1, Set<T> c2) {
    		Set<T> result = new HashSet<T>();
    		Iterator<T> iterator = c1.iterator();
    		while (iterator.hasNext()) {
    			T currentItem = iterator.next();
    			Iterator<T> iterator2 = c2.iterator();
    			while (iterator2.hasNext()) {
    				if (currentItem.equals(iterator2.next())) {
    					result.add(currentItem);
    					break;
    				}
    			}
    		}
    		return result;
    	}
    Y'aurait-il une raison pour laquelle le comportement est différent ? Avec mon implémentation, je passe bien dans le .equals(Object o)... (des fois qu'il appellerait un .equals(T t) par erreur)


    ++
    Gal'

  5. #5
    Membre chevronné
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2007
    Messages
    340
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2007
    Messages : 340
    Par défaut
    Ça doit venir du code de equals(Object), l'implémentation par défaut fait un simple == sur les objets, comment est-ce que tu l'as redéfinie ?

    Ou alors c'est ton code où tu utilises retainAll(Collection) qui est foireux.

  6. #6
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    Par défaut les comparaisons d'objets se font via la méthode equals(), comme c'est indiqué dans l'API de la classe Collection (dans le descriptif général de la classe). Mais il est tout à fait possible qu'une implémentation utilise un autre moyen de comparaison (comme un TreeSet couplé avec un Comparator par exemple).


    Quand à ton problème, je pense qu'il vient du fait que tu n'as pas dû redéfinir la méthode hashCode() de manière cohérente avec equals(), ce qui devrait être obligatoire dès qu'on redéfini equals !

    Pourquoi et comment redéfinir la méthode hashCode() ?

    a++

  7. #7
    Membre expérimenté Avatar de aperrin
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    221
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 221
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public boolean equals(Object other) {
    		if (!(other instanceof Matiere))
    			return false;
    		Matiere castOther = (Matiere) other;
     
    		return new EqualsBuilder().append(this.getCode(), castOther.getCode())
    				.isEquals();
    	}
     
    	public int hashCode() {
     
    		return new HashCodeBuilder().append(getCode()).toHashCode();
     
    	}
    Avec getCode() la clé de ton objet.
    EqualsBuilder et HashCodeBuilder vient de org.apache.common.lang

  8. #8
    Membre confirmé
    Inscrit en
    Décembre 2003
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 126
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Salut,

    Quand à ton problème, je pense qu'il vient du fait que tu n'as pas dû redéfinir la méthode hashCode() de manière cohérente avec equals(), ce qui devrait être obligatoire dès qu'on redéfini equals !
    T'es un chef

    Merci,


    Gal'

  9. #9
    Membre confirmé
    Inscrit en
    Décembre 2003
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 126
    Par défaut
    Citation Envoyé par aperrin Voir le message
    EqualsBuilder et HashCodeBuilder vient de org.apache.common.lang
    Heu... pourquoi je me mettrais une dépendance sur les org.apache.common ?

    C'est obligatoire ?

    Gal'

  10. #10
    Membre expérimenté Avatar de aperrin
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    221
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 221
    Par défaut
    Heu... pourquoi je me mettrais une dépendance sur les org.apache.common ?
    Ce n'est pas obligatoire mais ces bibliothèques fournissent entre autres des facilités pour obtenir un code (int) de haschage unique à partir de tous les type primaires en pouvant les mixer.
    Je suis partisan de ne pas réinventer la roue.
    Après comme tu le sens, c'est juste à titre d'exemple.
    Voici un exemple un peu plus complexe qui peu fournir des éclaircissements :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    public boolean equals(Object other) {
    		if ((this == other))
    			return true;
    		if (!(other instanceof EdC))
    			return false;
    		EdC castOther = (EdC) other;
     
    		return new EqualsBuilder().append(this.getNombreOption(),
    				castOther.getNombreOption()).append(this.getMatiere1(),
    				castOther.getMatiere1()).append(this.getMatiere2(),
    				castOther.getMatiere2()).append(this.getMatiere3(),
    				castOther.getMatiere3()).append(this.getMatiere4(),
    				castOther.getMatiere4()).append(this.getMatiere5(),
    				castOther.getMatiere5()).isEquals();
    	}
     
    	public int hashCode() {
    		return new HashCodeBuilder().append(getNombreOption()).append(
    				getMatiere1()).append(getMatiere2()).append(getMatiere3())
    				.append(getMatiere4()).append(getMatiere5()).toHashCode();
    	}
    Ici le code est composé de plusieurs getter de l'objet EdC.

  11. #11
    Membre confirmé
    Inscrit en
    Décembre 2003
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 126
    Par défaut
    Citation Envoyé par aperrin Voir le message
    Ce n'est pas obligatoire mais ces bibliothèques fournissent entre autres des facilités pour obtenir un code (int) de haschage unique à partir de tous les type primaires en pouvant les mixer.
    Je suis partisan de ne pas réinventer la roue.
    Après comme tu le sens, c'est juste à titre d'exemple.
    Oki, super.

    Dans mon cas, je vais plutôt redéfinir hashcode(), mais merci de cet exemple.

    Gal'

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 17/05/2009, 20h29
  2. Chat basé sur des sockets php5
    Par javhost dans le forum Développement
    Réponses: 1
    Dernier message: 12/07/2005, 16h21
  3. Réponses: 1
    Dernier message: 30/05/2005, 17h02
  4. [Collections] L'interface "Iterator" à quoi ça sert
    Par Samanta dans le forum Collection et Stream
    Réponses: 8
    Dernier message: 07/04/2005, 17h51
  5. [forms] Bloc basé sur une clause from
    Par plaineR dans le forum Forms
    Réponses: 11
    Dernier message: 16/12/2004, 12h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo