Java 的包装器 class 如何存储在 HashMap 中?

How wrapper class of Java is stored in HashMap?

请看下面的代码片段。

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

我知道 HashMap 使用节点数组来存储 K,V 对象。但是这里看起来hashmap只存储了Integer的原始值?因为从HashMap中取出来的值对象,连我们之前放的都不是。有谁知道 hashmap 如何处理包装器 class?

从Java 1.5 开始,Java 执行自动拆箱以在必要时将"wrapper types"(例如Integer)转换为相应的基本类型int。然后增量运算符可以处理结果 int.

当您执行 xInteger++ 时,它会在基元 int 上执行该操作。由于原始 int 是不可变的(它的包装器也是如此),因此当您执行 System.out.println(map.get('c')).

时不会反映出来

旁注:可以直接写:

Integer xInteger = 1; // no need for boxing

基元、基元包装器对象和许多其他类型(例如 java.lang.String)在 Java 中是不可变的。它们的内部状态无法更改。

xInteger++ 在幕后实际上与:

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)

更新映射中 Integer 值的唯一方法是将新的 Integer 分配给映射条目:

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

xInteger 变量的变化不会反映在 put 操作后的 HashMap 中,因为包装器 类 是 不可变的

Once you assign a value to a variable(wrapper class type) you won't be able to change that value


,但如果您使用任何 mutable 类,例如 AtomicInteger,更改将反映在 HashMap

例如:

        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'));

,输出

2
2
true

更多信息:Java Wrapper Classes are immutable? - Oracle community