java数值比较
什么是拆箱和装箱
本来在java SE5以前如果要生成一个数值为10的Integer对象,必须这样进行
Integer i = new Integer(10);
但提供了自动装箱技术之后就不用了,只需要这样:
Integer i = 10;
这个过程中会自动根据数值创建对应的 Integer对象,这就是装箱。
那什么是拆箱呢?顾名思义,跟装箱对应,就是自动将包装器类型转换为基本数据类型:
Integer i = 10; //装箱
int n = i; //拆箱
1、“==”
(1)Integer跟Integer之间的比较:
①如果是在-127~128之间,他们会拿到SMALL_VALUES数组里面的同一个对象,他们引用
到了同一个Integer对象,所以他们是相等的,看源码:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
②如果是不在这个范围的,则他们会创建两个Integer对象,所以不一样。
public class Main {
public static void main(String[] args) {
Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 200;
Integer i4 = 200;
System.out.println(i1==i2); //true
System.out.println(i3==i4); //false
}
}
(2)Integer跟int之间的比较:一定相等
因为如果一个封装类型(Integer)与一个基本数据类型==、+、-、*、/运算时,会将封装类进行拆箱,对基础数据类型进行运算。、
public class Main {
public static void main(String[] args) {
Integer i1 = 100;
int i2 = 100;
int i3 = 200;
Integer i4 = 200;
System.out.println(i1==i2);//true
System.out.println(i3==i4);//true
}
}
(3)Double与Double类型的比较
上面我们看到的Integer在比较的时候有一个-127~128范围内引用同一个对象,而超出这个范围之后就不再引用同一个对象。然而
在Double类型的时候并没有,这是因为浮点数据类型没有一个有限的集合里面,看源码:
public static Double valueOf(double d) {
return new Double(d);
}
我们可以做如下总结:
①Integer派别:Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。
②Double派别:Double、Float的valueOf方法的实现是类似的。每次都返回不同的对象。
所以Double创建的对象都是不一样的。所以不相等
public class Main {
public static void main(String[] args) {
Double i1 = 100;
Double i2 = 100;
double i3 = 100;
double i4 = 100;
System.out.println(i1==i2);//false
System.out.println(i3==i4);//true
}
}
(4)Double和double类型的比较
这个就跟Integer和int比较一样,封装类进行拆箱
2、equals的比较
(1)Double和double类型的比较
a.equals(b);要相等必须满足两个条件
①类型相同
②内容相同
首先来查看equals源码(我这里点开的是double的equals的源码):
public boolean equals(Object obj) {
return (obj instanceof Double)
&& (doubleToLongBits(((Double)obj).value) ==
doubleToLongBits(value));
}
可以看到equals传入的是一个Object对象,
所以当我们执行下面代码的时候
public class Main {
public static void main(String[] args) {
Double i1 = 100;
Double i2 = 100;
double i3 = 100;
double i4 = 100;
System.out.println(i1.equals(i3));//true
//System.out.println(i3==i4);
}
}
首先因为传入的是一个基本数据类型,所以要进行装箱,将double转为Double,所以第一个类型相同就
满足了,接下来再比较两者的内容,可以看到都是100,也是一样的,所以两者相同。
其他的Integer类型也是一样的。
3、不同类型的比较
(1)Long和Int类型的"=="和“equals”比较
首先我们可以直接来试一下对long和int直接比较。
发现结果是正确的,然后我们再来进行Long和Integer进行比较,发现直接报不同对象不能比较,跳过。
然后我们再来看一下下面的程序
现在我们改成:
public class Main {
public static void main(String[] args) {
Integer num1 = 100;
int num2 = 100;
Long num3 = 200l;
Integer num4 = 100;
System.out.println(num3 == (num1 + num2)); //true
System.out.println(num3.equals(num1 + num2)); //false
}
}
①可以发现,本来两个不能比较的Long类型和Integer类型,经过一个加运算的时候,首先int和Integer相加
有一个是基本数据类型所以转为了int类型,然后Long num3==int (200),又是一个基本数据类型跟Long比较,转型
所以结果是true.
②而第二个结果是false,理所应当的,因为equals比较的还要两个类型相同,而num1+num2是Integer类型,所以
所以不一样。