LeetCode刷第155题时, 提交答案出现奇怪的现象:

这种写法通过不了

public void pop() {
    //普通栈顶直接移除
    Integer pop = stack.pop();
    //最小栈顶, 若移除的是最小值才移除
    Integer minStackPeek = minStack.peek();
    
    if (pop == minStackPeek){
        minStack.pop();
    }
}

而将 Integer 改为 int 后可以通过

public void pop() {
    //普通栈顶直接移除
    int pop = stack.pop();
    //最小栈顶, 若移除的是最小值才移除
    int minStackPeek = minStack.peek();
    
    if (pop == minStackPeek){
        minStack.pop();
    }
}

思考后回想起 Java 中 Integer 存在一种缓存现象, 于是搜索资料并查看 Integer 类源码

equals()

x.equals(y) 方法先判断参数 y 是否和 x 是同类型对象

  • 是同类型对象

    • 再判断值是否相同

      值相同返回 true

      值不同返回 false

  • 不是同类型对象返回 false

另外, 当参数 y 是基本类型 int 时则会自动装箱为 Integer

==

  • 都是基本类型

    直接比较值

  • 一边基本类型, 一边包装类型

    • 同类型 如 Integer 与 int

      自动拆箱比较值

    • 不同类型

      先自动拆箱, 然后向上转型, 再比较值

      byte < short < int < long < floa t< double

  • 都是包装类型

    比较引用地址, 但要注意 IntegerCache 缓存现象

IntegerCache

Integer integer1 = 111;
Integer integer2 = Integer.valueOf(111);
Integer integer3 = new Integer(111);

//true
System.out.println(integer1 == integer2);
//false
System.out.println(integer1 == integer3);
//false
System.out.println(integer2 == integer3);

Integer integer1 = 111本质上调用的是 Integer.valueOf() 方法

但是, 在返回前, 会判断对象的值是否处于 [-128,127] 区间且 IntegerCache 中是否存在此对象

若是, 直接返回该引用, 若不是, 创建新对象

源码

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

IntegerCache 是 Integer 的内部类, 里面有 cache[] 数组

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() {}
}