Integer.valueOf(Integer intObj)运行过程及引发的其它问题
来源:互联网 发布:广东seo外包公司 编辑:程序博客网 时间:2024/05/22 08:02
首先看下下面的程序:
class Test
{
public static void main(String[] args)
{
System.out.println(Integer.valueOf(127)==Integer.valueOf(127));
System.out.println(Integer.valueOf(128)==Integer.valueOf(128));
}
}
返回结果为
为什么会出现这样的情况呢,127和128又有什么区别呢?
Integer.valueOf() 会返回一个Integer对象,当被处理的字符串在-128和127(包含边界)之间时,返回的对象是预先缓存的。这样看来第一行的两个Integer.valueOf()函数返回的是同一个对象,因此打印出true。而第二行的调用返回false是因为128没有被缓存,每次调用都会生成一个新的整型对象,因此两个128整型对象是不同的对象,返回false。
可能有的朋友不理解什么是预先缓存好的对象,其实,Integer类有一个静态缓存,存储了256个特殊的Integer对象,每个对象分别对应`-128 和127之间的一个值。如果传入的值(如:127)位于-128和127之间,就会从静态缓存中返回对象,如果超出了这个范围就会创建一个新的对象。因此,上述程序的第一行代码是从静态缓存中返回对象,是同一个对象,而第二行是新建对象,因此两个对象不相等。
写到这里我有遇到了另一个问题。大家都知道HashSet类中不允许有重复的元素,根据上面的知识可以知道,当我们执行两次hashSet.add(Integer.valueOf(127));时,由于两次传入的对象是同一个,所以实际上只存入一个;当我们执行两个hashSet.add(Integer.valueOf(128));时,由于两次传入的对象不是同一个,那么会存入两个。结果是不是这样呢?我们来试验一下:
import java.util.*;
class Test
{
public static void main(String[] args)
{
HashSet hs1 = new HashSet();
HashSet hs2 = new HashSet();
HashSet hs3 = new HashSet();
hs1.add(Integer.valueOf(127));
hs1.add(Integer.valueOf(127));
Iterator i = hs1.iterator();
while(i.hasNext())
{
System.out.println(i.next());
}
hs2.add(Integer.valueOf(128));
hs2.add(Integer.valueOf(128));
Iterator j = hs2.iterator();
while(j.hasNext())
{
System.out.println(j.next());
}
String s1 = new String("aa");
String s2 = new String("aa");
hs3.add(s1);
hs3.add(s2);
Iterator k = hs3.iterator();
While(k.hasNext())
{
System.out.println(k.next());
}
}
}
运行结果如下:
显然三段程序都只存入了一个对象,那么这是怎么回事呢?
实际上HashSet中存储先判断对象的hash值,如果一样再调用equals方法判断是否是同一对象,具体细节如下(引用网上的):
要想保证元素不重复,可两个元素是否重复应该依据什么来判断呢? 这就是Object.equals方法了。但是,如果每增加一个元素就检查一次,那么当元素很多时,后添加到集合中的元素比较的次数就非常多了。 也就是说,如果集合中现在已经有1000个元素,那么第1001个元素加入集合时,它就要调用1000次equals方法。这显然会大大降低效率。于是,Java采用了哈希表的原理。哈希(Hash)实际上是个人名,由于他提出一哈希算法的概念,所以就以他的名字命名了。 哈希算法也称为散列算法,是将数据依特定算法直接指定到一个地址上。初学者可以这样理解,hashCode方法实际上返回的就是对象存储的物理地址(实际可能并不是)。这样一来,当集合要添加新的元素时,先调用这个元素的hashCode方法,就一下子能定位到它应该放置的物理位置上。如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;如果这个位置上已经有元素了, 就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址。
由于Integer和String类重写了HashCode()方法,他们所创建出来的实例返回的hash是相同的,因此就看到第二段和第三段程序的结果和第一段一样,只存入一个。
【具体如何重写HashCode()方法以后再继续跟进】
【unboxing conversion】
- Integer.valueOf(Integer intObj)运行过程及引发的其它问题
- Integer.valueOf和Integer.parseInt及new Integer()的区别
- Integer的valueOf方法
- Integer.valueOf()
- Integer valueOf
- Integer valueOf
- Integer.valueOf()
- Integer.valueOf()和Integer.ParseInt()的区别
- Integer.parseInt()和Integer.valueOf()的区别
- Integer.valueOf和Integer.parseInt的区别
- Integer.parseInt()和Integer.valueOf()的区别
- 【转】Integer.valueof ,Integer.parseInt的区别
- Integer.parseInt()和Integer.valueOf()的详解
- Integer.parseInt()和Integer.valueOf()的区别
- Integer.valueof() Integer.parseInt()
- Integer.valueof() Integer.parseInt()
- Integer.valueof Integer.parseOf
- Integer的valueOf与ParsInt
- 到另外一个城市工作时,五险一金怎么办?
- 多重继承下,不同基类指针指向同一子类对象的地址
- Ruby安装
- 6.2 Git 工具 - 储藏(Stashing)
- ThoughtWorks待遇
- Integer.valueOf(Integer intObj)运行过程及引发的其它问题
- 6.4 Git 工具 - 重写历史
- (mini2440)建立交叉编译环境+配置linux内核
- hdu 5015 233 Matrix 矩阵快速幂
- Best Time to Buy and Sell Stock
- project facet java version 1.8
- Node.js v0.10.31API手册-简介
- HDU 5023 A Corrupt Mayor's Performance Art
- 奇偶剪枝