相关文章推荐
深沉的领结
·
[转]windows BLE编程 net ...
·
2 周前
·
愤怒的伤痕
·
扩展欧几里得算法+乘法逆元详解 - ...
·
1 月前
·
很酷的蚂蚁
·
【学术活动】宾夕法尼亚大学林共进教授访问我中 ...
·
5 月前
·
俊秀的小刀
·
关于QProcess的使用问题解释_setc ...
·
6 月前
·
憨厚的烈马
·
python ...
·
9 月前
·
憨厚的麻辣香锅
·
useMemo = useEffect + ...
·
1 年前
·
Code
›
Java的Integer与int互转__java string转int的方法
int转string
https://blog.51cto.com/iteyer/3231953
活泼的柚子
1 年前
JDK1.5以后,Java为我们提供了更为丰富的转换方法。
其中最值得一提的就是自动装包/自动拆包(AutoBoxing/UnBoxing)。
此功能大大丰富了基本类型(primitive type)数据与它们的包装类(Wrapper Class)
由于AutoBoxing的存在,以下代码在JDK1.5的环境下可以编译通过并运行。
Java代码
int
i =
0
;
Integer wrapperi = i;
还有其他方法?
JDK1.5为Integer增加了一个全新的方法:
Java代码
public
static
Integer valueOf(
int
i)
以下代码在JDK1.5的环境下可以编译通过并运行。
Java代码
int
i =
0
;
Integer wrapperi = Integer.valueOf(i);
此方法与new Integer(i)的不同处在于:
方法一调用类方法返回一个表示指定的 int 值的 Integer 实例。
方法二产生一个新的Integer对象。
JDK API文档中对这个新的valueOf方法有明确的解释:
如果不需要新的 Integer 实例,则通常应优先使用该方法,而不是构造方法 Integer(int),因为该方法有可能通过缓存经常请求的值而显著提高空间和时间性能。
但这个解释有点晦涩难懂。为什么该方法有可能通过缓存经常请求的值而显著提高性能?
通过反编译工具查看valueOf方法。
Java代码
* 返回一个表示指定的 int 值的 Integer 实例。如果不需要新的 Integer 实例,则
* 通常应优先使用该方法,而不是构造方法 Integer(int),因为该方法有可能通过
* 缓存经常请求的值而显著提高空间和时间性能。
* @param i an <code>int</code> value.
* @return a <tt>Integer</tt> instance representing <tt>i</tt>.
* @since 1.5
public
static
Integer valueOf(
int
i) {
final
int
offset =
128
;
if
(i >= -
128
&& i <=
127
) {
// must cache
return
IntegerCache.cache[i + offset];
return
new
Integer(i);
可以看到对于范围在-128到127的整数,valueOf方法做了特殊处理。
采用IntegerCache.cache[i + offset]这个方法。
从名字,我们可以猜出这是某种缓存机制。
进一步跟踪IntegerCache这个类,此类代码如下
Java代码
* IntegerCache内部类
* 其中cache[]数组用于存放从-128到127一共256个整数
private
static
class
IntegerCache {
private
IntegerCache(){}
static
final
Integer cache[] =
new
Integer[-(-
128
) +
127
+
1
];
static
{
for
(
int
i =
0
; i < cache.length; i++)
cache[i] =
new
Integer(i -
128
);
这就是valueOf方法真正的优化方法,当-128=<i<=127的时候,返回的是IntegerCache中的数组的值;当 i>127 或 i<-128 时,返回的是Integer类对象。
再举一个经常被提到的例子
Java代码
Integer i=
100
;
Integer j=
100
;
//print true
System.out.println(i==j);
此时的 i=IntegerCache.cache[i + 128] = IntegerCache.cache[228],
同样j = IntegerCache.cache[j + 128] = IntgerCache.cache[228]
因此 Integer引用i中存储的是cache数组第228号元素的地址。同理j也是同一个cache数组的第228号元素的地址(因为cache是Integer的static数组,只有一个)。
i==j比较的是引用地址,因此返回true。
Java代码
Integer i=
200
;
Integer j=
200
;
//print false
System.out.println(i==j);
此时的 i=new Integer(200); 同样j=new Integer(200) 。
两次都在堆中开辟了Integer的对象。
i 和 j 中存储的堆的对象地址是完全不同的。i==j 自然返回false。
引入缓存机制的作用何在?
接着上面的例子,假如我们在编程时大量需要值为100(100的范围在-128到127之间)的Integer对象。如果只能通过new来创建,需要在堆中开辟大量值一样的Integer对象。
这是相当不划算的,IntegerCache.cache很好的起到了缓存的作用。
当我们需要Integer i = 100的时候,直接从cache中取出第[100+128]号元素的地址赋值给引用i,再次需要Integer j = 100时,还是直接去这个地址赋值给j。是不是省去了在堆中不停的创建对象的代价了(空间,时间上的消耗都很大)。 这就是valueOf方法真正的提高性能之处。
正如JDK API文档对valueOf(int i)方法的描述,该方法有可能通过缓存经常请求的值而显著提高空间和时间性能。
valueOf(int i)的优化只针对于范围在-128到127的整数。
JDK1.5以后的Integer转int
由于UnBoxing的存在,以下代码在JDK1.5的环境下可以编译通过并运行。
Java代码
Integer wrapperi =
new
Integer(
0
);
int
i = wrapperi;
附:AutoBoxing与UnBoxing带来的转变
在JDK1.5之前,我们总是对集合不能存放基本类型而耿耿于怀。
以下代码在JDK1.5中成为了可能,试想下在JDK1.5之前该如何实现这段代码?
Java代码
int
x =
1
;
Collection collection =
new
ArrayList();
collection.add(x);
//AutoBoxing,自动转换成Integer.
Integer y =
new
Integer(
2
);
collection.add(y +
2
);
//y + 2为UnBoxing,自动转换成int。之后再次转换为Integer。
此特性同样适用于Map
Java代码
Map map =
new
HashMap();
int
x =
1
;
Integer y =
new
Integer(
2
);
int
z =
3
;
map.put(x,y + z);
//x自动转换成Integer。y+z自动转换成int。之后再次转换为Integer。
推荐文章
深沉的领结
·
[转]windows BLE编程 net winform 连接蓝牙4.0_51CTO博客_windows蓝牙传输
2 周前
愤怒的伤痕
·
扩展欧几里得算法+乘法逆元详解 - cglong - 博客园
1 月前
很酷的蚂蚁
·
【学术活动】宾夕法尼亚大学林共进教授访问我中心并做学术报告 - 清华大学统计学研究中心
5 月前
俊秀的小刀
·
关于QProcess的使用问题解释_setcreateprocessargumentsmodifier-CSDN博客
6 月前
憨厚的烈马
·
python 将变量名转化为同名字符串_lua 变量名可以转成同名字符串-CSDN博客
9 月前
憨厚的麻辣香锅
·
useMemo = useEffect + useState ? - 知乎
1 年前