2010-02-20 18 views
11

Selon le javadoc HashSet, HashSet.contains renvoie uniquement un booléen. Comment puis-je "trouver" un objet dans un hashSet et le modifier (ce n'est pas un type de données primitif)?comment rechercher et renvoyer des objets dans java hashset

Je vois que HashTable a une méthode get(), mais je préférerais utiliser l'ensemble.

+0

merci toutes les personnes! Mon objet contient en fait une liste liée que j'ai besoin de mettre à jour fréquemment, donc je pense que je vais aller avec HashTable plutôt que faire une itération coûteuse pour chaque mise à jour d'objet. – user276712

Répondre

11

Vous pouvez supprimer un élément et en ajouter un autre.

La modification d'un objet lorsqu'il est dans un ensemble de hachage est une recette de désastre (si la modification modifie la valeur de hachage ou le comportement d'égalité).

+1

Ce n'est pas totalement vrai. Il est prudent de modifier un élément HashSet si la modification n'a pas d'impact sur l'égalité de l'objet (et le code de hachage). Par exemple, si equals et hashCode n'ont pas été remplacés, le changement est sûr car l'égalité n'est pas modifiée. –

+2

Oui, et c'est pourquoi j'ai écrit la partie entre parenthèses. – starblue

2

Vous pouvez parcourir l'ensemble pour trouver votre objet.

Un mot d'avertissement de la API doc si:

« Note: Un grand soin doit être exercé si des objets mutables sont utilisés comme éléments de définir le comportement d'un ensemble n'est pas spécifié si la valeur d'un objet. changé d'une manière qui affecte les comparaisons égales alors que l'objet est un élément de l'ensemble. "

+2

"Vous pouvez itérer ..." mais bien sûr, si vous faites cela, la mise à jour d'un élément set devient une opération 'O (N)'. –

12

Pour citer la source du stock Sun java.util.HashSet:

public class HashSet<E> 
    extends AbstractSet<E> 
    implements Set<E>, Cloneable, java.io.Serializable 
{ 
    static final long serialVersionUID = -5024744406713321676L; 

    private transient HashMap<E,Object> map; 

Vous payez pour une carte, vous pourriez aussi bien l'utiliser.

+3

Je pense que vous essayez de dire "utiliser un HashMap" ... correct? :-) –

+5

Oui. Désolé, parfois je ne peux pas résister à l'envie de faire de petites énigmes de réponses. – bmargulies

0
Object oldobj; //object to modify 
if (hashset.remove(oldobj)) { 
    Object newobj; //modified object 
    hashset.add(newobj); 
} 
0

Quelque chose comme:

MyObject obj = new MyObject(); 
HashSet hashSet = new HashSet(); 
hashSet.add(obj); 

if (hashSet.contains(obj) == true) { 
    hashSet.remove(obj); 
    obj.setSomething(); 
    hashSet.add(obj); 
} 
+3

1. '== true' - est inutile 2. vous n'avez pas vérifié la valeur de retour de' .remove (obj) ' 3.' .contains() 'est inutile si vous supprimez à l'étape suivante –

+1

Désespoir que tout est vrai, vous ne devriez pas être si difficile :) – kovica

-1

j'ai rencontré le même problème et est venu avec la solution suivante (il doit implémenter l'interface ensemble, mais pas toutes les méthodes sont ici)

public class MySet<T> implements Set<T>{ 

    private HashMap<T,T> items = new HashMap<T,T>(); 


    public boolean contains(Object item) 
    { 
     return items.containsKey(item); 
    } 

    public boolean add(T item) 
    { 
     if (items.containsKey(item)) 
      return false; 
     else 
     { 
      items.put(item, item); 
      return true; 
     } 
    } 

    public T get(T item) 
    { 
     return items.get(item); 
    } 
} 
+1

Il n'est pas nécessaire de déléguer. Utilisez simplement HashMap au lieu de HashSet. – mostruash