1. int 是基础数据类型, Integer 是类, 是对 int的封装对象,具备对象的一切特性。
2. 比较
int a = 300;
int b = 300;
Integer c = 300;
Integer d = 300;
Integer e = new Integer(300);
Integer f = new Integer(300);
Integer g = Integer.valueOf(300);
Integer h = Integer.valueOf(300);
Integer i = Integer.valueOf("300");
Integer j = Integer.valueOf("300");
Integer k = Integer.parseInt("300");
Integer l = Integer.parseInt("300");
System.out.println(a == b); //true
System.out.println(a == c); //true
System.out.println(a == e); //true
System.out.println(a == g); //true
System.out.println(a == i); //true
System.out.println(a == k); //true
System.out.println("================");
System.out.println(c == d); //false
System.out.println(c == e); //false
System.out.println(c == g); //false
System.out.println(c == i); //false
System.out.println(c == k); //false
System.out.println("================");
System.out.println(e == f); //false
System.out.println(e == g); //false
System.out.println(e == i); //false
System.out.println(e == k); //false
System.out.println("================");
System.out.println(g == h); //false
System.out.println(g == i); //false
System.out.println(g == k); //false
System.out.println("================");
System.out.println(i == j); //false
System.out.println(i == k); //false
System.out.println("================");
System.out.println(k == l); //false
Integer是一个对象,==比较的是引用地址,与 int 比较,jvm会将Integer转化为int, 所以结果为true,但Integer之间比较时,如果是用new创建的对象,一定返回false。
不是用new创建的四种情况,其实是一种,在编译时 , Integer c = 300;会编译为 Integer c = Integer.valueOf(300);
而 Integer i = Integer.valueOf("300"); 实际上也是 valueOf(int)的调用。看源码:
public static Integer valueOf(String s) throws NumberFormatException {
return Integer.valueOf(parseInt(s, 10));
}
Integer k = Integer.parseInt("300");这实际上就是 Integer k = 300; parseInt(str)方法返回的基础数据类型int。
上面的例子中这四种情况的比较返回false,是因为300>127,在源码中,128以下是数据是缓存的,而大于127是需要新建 new 对象,所以当数值大于300时,这四种情况都是new创建对象。
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
IntegerCache.low=-128,而 IntegerCache.high=127
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
所以,上面的例子,如果把300换成小于128的数,不使用new创建的Integer之间的比较会返回true。
int a = 100;
int b = 100;
Integer c = 100;
Integer d = 100;
Integer e = new Integer(100);
Integer f = new Integer(100);
Integer g = Integer.valueOf(100);
Integer h = Integer.valueOf(100);
Integer i = Integer.valueOf("100");
Integer j = Integer.valueOf("100");
Integer k = Integer.parseInt("100");
Integer l = Integer.parseInt("100");
System.out.println(a == b); //true
System.out.println(a == c); //true
System.out.println(a == e); //true
System.out.println(a == g); //true
System.out.println(a == i); //true
System.out.println(a == k); //true
System.out.println("================");
System.out.println(c == d); //true
System.out.println(c == e); //false
System.out.println(c == g); //true
System.out.println(c == i); //true
System.out.println(c == k); //true
System.out.println("================");
System.out.println(e == f); //false
System.out.println(e == g); //false
System.out.println(e == i); //false
System.out.println(e == k); //false
System.out.println("================");
System.out.println(g == h); //true
System.out.println(g == i); //true
System.out.println(g == k); //true
System.out.println("================");
System.out.println(i == j); //true
System.out.println(i == k); //true
System.out.println("================");
System.out.println(k == l); //true
3. 在List中的比较
常用List<Integer> list = new ArrayList<Integer>();来缓存数据,会用到List的方法contains(Object o).使用上面例子中的数据,在 list.add(Object o)上面任一数据,再使用 list.contains(Object o),参数使用上面中的任一数据,返回的结果都是true。因为 contains(Object o)方法比较的是Integer中的value。
看下List源码
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
可以看到,contains比较时是使用的equals方法,而Integer的equals方法比较的是value。
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
同理,其他Long,Float在List中也是一样的,所以可以放心的使用List的contains检查数据。