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
请看下面的代码片段。
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