int和Integer的比较
【1】基本介绍
Java中的int和Integer在比较时是有区别的。
(1)int是Java中的一种基本数据类型,属于值类型,可以直接比较。
(2)而Integer则是Java中的一种包装类型,属于引用类型,不能直接比较。
当我们对两个Integer对象进行比较时,实际上是在比较它们所引用的对象在内存中的地址,而不是其所代表的数值。因此,如果直接使用==
进行比较,通常不能得到正确的结果。
【2】Integer和int的案例
(1)Integer和Integer之间的比较
针对Integer
对象,我们可以使用equals()
方法进行比较。equals()
方法会先比较对象的类型是否一致,如果不一致则返回false。如果类型一致,则比较对象所代表的数值是否相等,如果相等则返回true,否则返回false。
Integer a = 10;
Integer b = 10;
System.out.println(a == b); // true
System.out.println(a.equals(b)); // true
Integer c = 128;
Integer d = 128;
System.out.println(c == d); // false
System.out.println(c.equals(d)); // true
在上面的代码中,我们声明了两个Integer
对象a和b,它们所引用的对象在内存中地址相同,因此使用==
进行比较时返回true。使用equals()
进行比较时同样返回true。另外,我们声明了两个Integer
对象c和d,它们所引用的对象在内存中地址不同,因此使用==
进行比较时返回false。但是因为它们所代表的数值相同,因此使用equals()
进行比较时返回true。
需要注意的是,由于Java中对整型常量池的规定,对于-128~127之间的整数,无论我们创建多少个Integer
对象,它们所引用的对象在内存中地址都是相同的,因此使用==
进行比较时会返回true。但是对于超过这个范围的整数,每创建一个Integer
对象,就会在内存中新分配一个对象,因此==
进行比较时会返回false。所以在比较Integer
对象时,最好使用equals()
方法进行比较。
总结:如果Integer类型的两个数相等,如果范围在-128~127(默认),那么用返回true,其余的范会false。Integer类型比较大小,要么调用Integer.intValue()转为基本类型用比较,要么直接用equals比较。
(2)int和int之间的比较
两个基本类型int进行相等比较,直接用==即可
(3)int和Integer之间的比较
一个基本类型int和一个包装类型Integer比较,用==也可,比较时候,Integer类型做了拆箱操作。
(4)Java Integer.compareTo()比较大小
public class IntegerCompareToDemo {
public static void main(String args[]) {
Integer b = 5;
Integer c = 15;
System.out.println(b.compareTo(c)); //输出-1
b = 15;
System.out.println(b.compareTo(c)); //输出0
b = 20;
System.out.println(b.compareTo(c)); //输出1
}
}
(5)总结
(1)Integer和Integer比较用equals
(2)int和int比较用==
(3)int和Integer比较用==,Integer会自动拆箱
(4)==在基本数据类型int中比较的是两个基本数据类型的值是否相等
==引用数据类型Integer中比较的是引用的对象是否相等,即是否引用了同一个对象,比较的是地址
【3】Long和long的案例
1.
Long aLong=(long) 128;
Long bLong=(long) 128;
System.out.println(aLong==bLong);
结果:false
===========================
2.
Long aLong=(long) 127;
Long bLong=(long) 127;
System.out.println(aLong==bLong);
结果:true
===========================
3.
long aLong= 128;
long bLong= 128;
System.out.println(aLong==bLong);
结果:true
===========================
long aLong= 127;
long bLong= 127;
System.out.println(aLong==bLong);
结果:true
==在基本数据类型中比较的是两个基本数据类型的值是否相等
==引用数据类型中比较的是引用的对象是否相等,即是否引用了同一个对象,比较的是地址
所以3,4的结果都为true,那么1,2,同是Long型,同是==,为什么结果不一样呢?
看看源代码:
private static class LongCache {
private LongCache(){}
static final Long cache[] = new Long[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Long(i - 128);
}
}
public static Long valueOf(long l) {
final int offset = 128;
if (l >= -128 && l <= 127) { // will cache
return LongCache.cache[(int)l + offset];
}
return new Long(l);
}
原来是因为Long中有一个静态的内部类LongCache,专门用于缓存-128至127之间的值,一共256个元素。
如果仅仅是缓存下来而不去使用那么就没有任何意义。valueOf(long l)就是使缓存派上用场的方法,它会判断传入的参数是否在-128-127之间,如果是则直接从缓存中返回对应的引用,否则新创建一个Long的实例。
解决办法
(1)先通过.longValue()方法获取Long对象的基本类型long的值之后再做比较的。
Long aLong=(long) 128;
Long bLong=(long) 128;
System.out.println(aLong.longValue()==bLong.longValue());
结果 :true
(2)重写equals方法,方便使用
public boolean equals(Object obj) {
if (obj instanceof Long) {
return value == ((Long)obj).longValue();
}
return false;
}
【4】Long和Integer的案例
然后想通过stream的filter过滤出数据,使用的条件是Long.equals(Integer),然后打印测试了一下
List<ContractExpensesEditVo.ContractExpensesDetail> basicList = contractExpensesDetail
.stream().filter(obj ->{
System.out.println("Long.equals(Integer):"+obj.getFirstSubjectId().equals(ContractApiCode.BASIC_FEE.getCode()));
System.out.println("Integer.equals(Long):"+ContractApiCode.BASIC_FEE.getCode().equals(obj.getFirstSubjectId()));
System.out.println(obj.getFirstSubjectId().longValue()==ContractApiCode.BASIC_FEE.getCode());
return obj.getFirstSubjectId().longValue()==ContractApiCode.BASIC_FEE.getCode();
} )
.collect(Collectors.toList());
结果:
按理说equals比较的是值,应该是true的,但是打印出来的是false,原因是Long和Integer的类都重写了equals方法如下:
//Long
public boolean equals(Object obj) {
if (obj instanceof Long) {
return value == ((Long)obj).longValue();
}
return false;
}
//Integer
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
他们的equals方法都会先判断类型然后再比较,类型不同直接返回false
换一种写法
1.obj.getFirstSubjectId().longValue() == ContractApiCode.CUSTOMS_FEE.getCode()
2.ContractApiCode.BASIC_FEE.getCode().equals(obj.getFirstSubjectId().longValue())
这么写就变成了longInteger,Integer会进行拆箱转为int类型,然后向上转型为long类型,也就是变为了longlong ,这样就可以比较了