Maison > Java > javaDidacticiel > le corps du texte

Comment modifier la valeur dans Hashmap en fonction de la valeur clé en Java

王林
Libérer: 2023-05-13 14:25:06
avant
3247 Les gens l'ont consulté

    Modifiez la valeur du Hashmap en fonction de la valeur de la clé

    S'il n'y a pas de clé dans la carte d'origine, elle sera créée. S'il y a la clé d'origine, la valeur d'origine sera écrasée par la valeur

    map.put(key,value);
    Copier après la connexion
    .

    Cette implémentation en ajoute un à la valeur d'origine (prémisse Il y a cette clé)

    map.put(key,map.get(key)+1);
    Copier après la connexion

    La valeur correspondant à la clé peut être obtenue comme suit. Sinon, la valeur par défaut peut être renvoyée

    map.getOrDefault(key,value);
    Copier après la connexion

    La valeur peut-elle être obtenue correctement après. la clé de HashMap est modifiée ?

    Une série de paires clé-valeur stockées dans HashMap, où la clé est un type personnalisé. Après l'avoir mis dans HashMap, nous modifions les attributs d'une certaine clé en externe, puis nous utilisons cette clé pour supprimer des éléments de HashMap. Que retournera HashMap à ce moment-là ?

    Les réponses de plusieurs personnes dans notre bureau sont incohérentes. Certains disent qu'il renvoie null, et d'autres disent qu'il peut renvoyer une valeur normalement. Mais quelle que soit la réponse, il n’y a aucune raison solide. J'ai pensé que cette question était assez intéressante, alors j'ai écrit un test de code. Le résultat est nul. Il convient de noter que notre classe personnalisée remplace la méthode hashCode. Je pense que ce résultat est un peu inattendu, car nous savons que HashMap stocke les types de référence et nous avons mis à jour la clé à l'extérieur, ce qui signifie que la clé dans HashMap est également mise à jour, ce qui signifie que la valeur de retour hashCode de cette clé se produira également . changement. À ce stade, le hashCode de key et HashMap doit être le même que le hashCode de l'élément, et égal à retournera certainement vrai, car il s'agit du même objet, alors pourquoi ne peut-il pas renvoyer la valeur correcte ?

    Cas de test

    Il y a 2 cas ici, l'un est la classe Person et l'autre est la classe Student. Vérifions le point de vue ci-dessus (avec conclusion) :

    • Si la modification des propriétés de l'objet changera son. hashcode => Oui

    • L'attribut sera-t-il affecté par la modification de la valeur lors de l'accès au HashMap => La valeur est nulle

    package tech.luxsun.interview.luxinterviewstarter.collection;
     
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import java.util.HashMap;
     
    /**
     * @author Lux Sun
     * @date 2021/4/22
     */
    public class MapDemo0 {
     
        public static void main(String[] args) {
            HashMap<Object, Object> map = new HashMap<>();
     
            // Person Case
            Person p = new Person("Bob", 12);
            map.put(p, "person");
            System.out.println(p.hashCode());
            System.out.println(map.get(p));
     
            p.setAge(13);
            System.out.println(p.hashCode());
            System.out.println(map.get(p));
     
            // Student Case
            Student stu = new Student("Bob", 12);
            map.put(stu, "student");
            System.out.println(stu.hashCode());
            System.out.println(map.get(stu));
     
            stu.setAge(13);
            System.out.println(stu.hashCode());
            System.out.println(map.get(stu));
        }
    }
     
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    class Person {
        private String name;
        private Integer age;
     
        public int hashCode() {
            return 123456;
        }
    }
     
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    class Student {
        private String name;
        private Integer age;
    }
    Copier après la connexion

    Résultat de sortie

    123456

    person
    123456
    person
    71 154
    student
    71213
    null

    Code source

    hashCode code source

    public int hashCode() {
        int PRIME = true;
        int result = 1;
        Object $age = this.getAge();
        int result = result * 59 + ($age == null ? 43 : $age.hashCode());
        Object $name = this.getName();
        result = result * 59 + ($name == null ? 43 : $name.hashCode());
        return result;
    }
    Copier après la connexion

    map.get code source

    /**
     * Returns the value to which the specified key is mapped,
     * or {@code null} if this map contains no mapping for the key.
     *
     * <p>More formally, if this map contains a mapping from a key
     * {@code k} to a value {@code v} such that {@code (key==null ? k==null :
     * key.equals(k))}, then this method returns {@code v}; otherwise
     * it returns {@code null}.  (There can be at most one such mapping.)
     *
     * <p>A return value of {@code null} does not <i>necessarily</i>
     * indicate that the map contains no mapping for the key; it&#39;s also
     * possible that the map explicitly maps the key to {@code null}.
     * The {@link #containsKey containsKey} operation may be used to
     * distinguish these two cases.
     *
     * @see #put(Object, Object)
     */
    public V get(Object key) {
        Node<K,V> e;
        return (e = getNode(hash(key), key)) == null ? null : e.value;
    }
     
     
    /**
     * Computes key.hashCode() and spreads (XORs) higher bits of hash
     * to lower.  Because the table uses power-of-two masking, sets of
     * hashes that vary only in bits above the current mask will
     * always collide. (Among known examples are sets of Float keys
     * holding consecutive whole numbers in small tables.)  So we
     * apply a transform that spreads the impact of higher bits
     * downward. There is a tradeoff between speed, utility, and
     * quality of bit-spreading. Because many common sets of hashes
     * are already reasonably distributed (so don&#39;t benefit from
     * spreading), and because we use trees to handle large sets of
     * collisions in bins, we just XOR some shifted bits in the
     * cheapest possible way to reduce systematic lossage, as well as
     * to incorporate impact of the highest bits that would otherwise
     * never be used in index calculations because of table bounds.
     */
    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }
     
    /**
     * Implements Map.get and related methods
     *
     * @param hash hash for key
     * @param key the key
     * @return the node, or null if none
     */
    final Node<K,V> getNode(int hash, Object key) {
        Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
        if ((tab = table) != null && (n = tab.length) > 0 &&
            (first = tab[(n - 1) & hash]) != null) {
            if (first.hash == hash && // always check first node
                ((k = first.key) == key || (key != null && key.equals(k))))
                return first;
            if ((e = first.next) != null) {
                if (first instanceof TreeNode)
                    return ((TreeNode<K,V>)first).getTreeNode(hash, key);
                do {
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        return e;
                } while ((e = e.next) != null);
            }
        }
        return null;
    }
    Copier après la connexion
    En bref

    Vous pouvez voir qu'une table est obtenue en premier, qui est en fait un tableau. Recherchez ensuite la valeur correspondant à la clé dans le tableau. Le critère de recherche est que le hachage est égal au hachage du paramètre transmis et remplit l'une des deux autres conditions : k = e.key, ce qui signifie qu'il s'agit du même objet, ou de la clé de la cible égale. de la clé transmise. Notre problème réside dans le hash(key.hashCode()). Vous pouvez voir que HashMap hache le hashCode de la clé lors du stockage des éléments. Le hachage obtenu sera finalement utilisé comme base pour l'emplacement de stockage de l'élément. Correspondant à notre situation : lors du premier stockage, la fonction de hachage utilise key.hashCode comme paramètre pour obtenir une valeur, puis stocke l'élément dans un certain emplacement en fonction de cette valeur.

    Lorsque nous récupérons l'élément, la valeur de key.hashCode a changé, donc le résultat de la fonction de hachage ici a également changé, donc lorsqu'il essaie d'obtenir l'emplacement de stockage de cette clé, il ne peut pas obtenir la valeur correcte, ce qui en résulte. dans l'élément cible n'étant finalement pas trouvé. Pour le retourner correctement, c'est très simple. Changer la méthode hashCode de la classe Person pour que son hashCode ne dépende pas de l'attribut que l'on souhaite modifier. Cependant, cela ne doit pas être fait en développement réel. les attributs des deux objets sont différents, différentes valeurs de hashCode peuvent être renvoyées lorsqu'elles sont exactement les mêmes.

    La conclusion est donc qu'après avoir placé l'objet dans un HashMap, ne modifiez pas les attributs de la clé sauf si vous remplacez la méthode hashCode de la classe d'entité qui n'est pas soumise aux restrictions d'attributs.

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

    Étiquettes associées:
    source:yisu.com
    Déclaration de ce site Web
    Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
    Tutoriels populaires
    Plus>
    Derniers téléchargements
    Plus>
    effets Web
    Code source du site Web
    Matériel du site Web
    Modèle frontal
    À propos de nous Clause de non-responsabilité Sitemap
    Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!