Veuillez consulter l'extrait de code suivant.
Integer xInteger = new Integer(1); map.put('c', xInteger); xInteger++; System.out.println(xInteger); // 2 System.out.println(map.get('c')); // 1 System.out.println(xInteger == map.get('c')); // false
Je sais que HashMap utilise un tableau de Node pour stocker des objets K, V. Mais ici, il semble que hashmap ne stocke que la valeur primitive de l'Integer? Parce que l'objet de valeur récupéré de HashMap n'est même pas celui que nous avons mis avant. Quelqu'un sait-il comment hashmap gère la classe wrapper?
3 Réponses :
À partir de Java 1.5, Java effectue un déballage automatique pour convertir les "types d'encapsuleurs" tels que Integer en le type primitif correspondant int
si nécessaire. Ensuite, l'opérateur d'incrémentation peut travailler sur le int
résultant.
Lorsque vous faites xInteger ++
, il l'exécute sur la primitive int
. Puisque la primitive int
est immuable (il en est de même pour son wrapper), elle n'est pas reflétée lorsque vous faites System.out.println (map.get ('c'))
.
Note latérale: Vous pouvez directement écrire:
Integer xInteger = 1; // no need for boxing
Les primitives, les objets d'encapsulation primitifs et un certain nombre d'autres types (par exemple java.lang.String
) sont immuables en Java. Leur état interne ne peut pas être modifié.
Faire xInteger ++
est, dans les coulisses, effectivement le même que:
int i = 1; map.put('c', i); // will be auto-boxed to Integer map.put('c', ++i); // will do i = i + 1, and auto-box the result to Integer
Le seul La façon de mettre à jour la valeur d'un Integer
dans une carte, est d'attribuer un nouvel Integer
à l'entrée de la carte:
int i = xInteger.intValue(); // get primitive value (unboxing) i = i + 1; // assign new primitive value to variable xInteger = Integer(i); // create new object with updated value (boxing)
La modification de la variable xInteger
ne sera pas reflétée dans la HashMap
après l'opération put
, car les classes wrapper sont immuables
Une fois que vous avez attribué une valeur à une variable (type de classe wrapper), vous ne pourrez plus changer cette valeur
, mais si vous utilisez des classes mutables telles que AtomicInteger
, le changement sera reflété dans le HashMap
Par exemple:
2 2 true
, sortie
Map<Character, AtomicInteger> map = new HashMap<>(); AtomicInteger xInteger = new AtomicInteger(1); map.put('c', xInteger); xInteger.incrementAndGet(); System.out.println(xInteger); // 2 System.out.println(map.get('c')); // 1 System.out.println(xInteger == map.get('c'));
Plus d'informations: Les classes Java Wrapper sont immuables? - Communauté Oracle
Les primitives et les objets wrapper primitifs sont immuables. Il en va de même pour les chaînes.