54 votes

Java HashSet vs HashMap

Je comprends qu' HashSet est basé sur HashMap mise en œuvre mais il est utilisé lorsque vous avez besoin d'un ensemble unique d'éléments. Alors, pourquoi dans le prochain code quand même de mettre des objets dans la carte et ensemble nous avons la taille de ces deux collections est égal à 1? Ne devrait pas la taille de la carte 2? Parce que si la taille de chaque collection est égal, je ne vois pas la différence de l'utilisation de ces deux collections.

    Set testSet = new HashSet<SimpleObject>();
    Map testMap = new HashMap<Integer, SimpleObject>(); 

    SimpleObject simpleObject1 = new SimpleObject("Igor", 1);
    SimpleObject simplObject2 = new SimpleObject("Igor", 1);
    testSet.add(simpleObject1);
    testSet.add(simplObject2);


    Integer key = new Integer(10);

    testMap.put(key, simpleObject1);
    testMap.put(key, simplObject2);

    System.out.println(testSet.size());
    System.out.println(testMap.size());

La sortie est 1 et 1.

SimpleObject code

public class SimpleObject {

private String dataField1;
private int dataField2;

public SimpleObject(){}

public SimpleObject(String data1, int data2){
    this.dataField1 = data1;
    this.dataField2 = data2;
}

public String getDataField1() {
    return dataField1;
}

public int getDataField2() {
    return dataField2;
}

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result
            + ((dataField1 == null) ? 0 : dataField1.hashCode());
    result = prime * result + dataField2;
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    SimpleObject other = (SimpleObject) obj;
    if (dataField1 == null) {
        if (other.dataField1 != null)
            return false;
    } else if (!dataField1.equals(other.dataField1))
        return false;
    if (dataField2 != other.dataField2)
        return false;
    return true;
 }
}

130voto

Bozho Points 273663

La carte détient les clés uniques. Lorsque vous appelez put avec une clé qui existe dans la carte, l'objet en vertu de cette clé est remplacé par le nouvel objet. Donc la taille 1.

La différence entre les deux est évidente:

  • en Map vous stockez des paires clé-valeur
  • en Set vous stocker uniquement les touches

En fait, un HashSet a HashMap champ, et à chaque fois qu' add(obj) est invoquée, l' put méthode est appelée sur la carte sous-jacente map.put(obj, DUMMY) - où l'objet dummy est un private static final Object DUMMY = new Object(). Si la carte est remplie avec votre objet comme une clé et une valeur qui n'a aucun intérêt.

7voto

ColinD Points 48573

Une clé dans une Map ne peut de la carte à une valeur unique. Donc la deuxième fois que vous put à la carte avec la même clé, il remplace la première entrée.

6voto

lobster1234 Points 4572

Dans le cas de la HashSet, en ajoutant le même objet sera plus ou moins un no-op. Dans le cas d'une table de hachage, de mettre une nouvelle clé,valeur de paire avec une clé existante remplacer la valeur existante pour définir une nouvelle valeur pour cette clé. Ci-dessous, j'ai ajouté equals() vérifie à votre code:

SimpleObject simpleObject1 = new SimpleObject("Igor", 1);
SimpleObject simplObject2 = new SimpleObject("Igor", 1);
//If the below prints true, the 2nd add will not add anything
System.out.println("Are the objects equal? " , (simpleObject1.equals(simpleObject2));
testSet.add(simpleObject1);
testSet.add(simplObject2);


Integer key = new Integer(10);
//This is a no-brainer as you've the exact same key, but lets keep it consistent
//If this returns true, the 2nd put will overwrite the 1st key-value pair.
testMap.put(key, simpleObject1);
testMap.put(key, simplObject2);
System.out.println("Are the keys equal? ", (key.equals(key));
System.out.println(testSet.size());
System.out.println(testMap.size());

0voto

David Prun Points 1624

Je pense que la différence majeure est, HashSet est stable dans le sens, il ne remplace pas des doublons de valeur (si elle est trouvée après l'insertion de la première clé unique, juste jeter tous les futurs doublons), et HashMap fera l'effort de remplacer l'ancien avec le nouveau double valeur. Donc il doit y avoir des coûts additionnels dans la HashMap d'insérer un nouvel article en double.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X