Java 数值相等判断详解(特别注意包装类型之间的比较)

Java数值类型分为基本类型,包装类型。

  • 基本类型:byte、short、 int、long、float和double
  • 包装类型:Byte、Short、Integer、Long、Float和Double

数值比较可分为基本类型之间比较,基本类型与包装类类型比较,包装类型之间的比较。

基本类型比较

基本类型之间只能使用“==”做相等比较。比较结果就是数值是否相等。

int a=1, b=1,c=2;
System.out.println(a==b);  //输出true
System.out.println(a==c);  //输出false

基本类型与包装类型比较

包装类型可使用“==”和.equals()方法与基本类型的数字比较。

  • ==:使用==比较,包装类型对象会先拆箱(转为基本类型)后再和基本类型比较,比较结果为数值是否相等。
  • .equals(): 包装类型的.equals()方法比较包装的数值是否相等。
Integer a=1, b=1,c=2;
System.out.println(a==b);  //输出true
System.out.println(a==c);  //输出false

基本类型与包装类型的这两种方式都是比较数值,结果符合比较预期。

整型包装类型比较

包装类型的整型和浮点型它们各自的比较有一点差别,分开说明。

包装类型比较方式有==和equals()方法。

==比较:

以Integer为示例:

Integer a1 = 127, b1 = 127;
Integer a2 = 128, b2 = 128;
Integer a3 = new Integer(127), b3= new Integer(127);

System.out.println(a1 == b1);  //输出为true
System.out.println(a2 == b2);  //输出为false
System.out.println(a3 == b3);  //输出为false

示例中,同样是数值比较,a1和b1比较结果为true,而a2和b2比较结果却为false。两者之间的差别只有数值不同。a3和b3比较结果为false,虽然它们的数值都是127,与a1和b1不同的地方是,a3和b3是通过构造函数赋值。

Java出于性能考虑会在内存里构造一些常量池,这种做法叫做享元模式。在整型包装类型里用了这种方式,数值缓存在Integer内部类IntegerCache里,代码如下:

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

在IntegerCache的代码可以看出,缓存的的范围默认为[-128,127]。你也可以使用java.lang.Integer.IntegerCache.high属性来设置缓存的最大值,但最大值不能超过(Integer.MAX_VALUE - 129)。

在看下构造Integer对象的两种主要方法:

public Integer(int value) {
    this.value = value;
}

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

第一种是通过Integer构造函数来构造对象, 第二种是使用valueOf(int i)方法。

从valueOf(int i)代码可以看到,当参数i值在IntegerCache指定的范围内时,共享使用IntegerCache缓存的Integer对象。超出它的范围则直接构造Integer对象。

首先要知道,引用类型的对象的==比较是判断两个对象的内存地址是否一样,相同则为true。包装类型是引用类型的一种。

示例里比较解释如下:

  1. a1==b1:数值赋值,数值在[-128,127]范围内,a1和b1实际对象为IntegerCache缓存对象,对象地址相同,结果为true。
  2. a2==b2:数值赋值,数值超出[-128,127]范围,a2和b2为新构建对象,对象对应的内存地址不相同,结果为false。
  3. a3==b3:新构建对象,尽管数值相同,但对象内存地址不同,结果为false。

equals()比较:

equals()方法比较的是数值,数值相等则为true;上面的例子

System.out.println(a1.equals(b1));   //true
System.out.println(a2.equals(b2));   //true
System.out.println(a3.equals(b3));   //true

浮点包装类型比较

和其他引用类型比较一样。==比较的是包装类型对象的内存地址。而浮点包装类型equals()方法比较的是数值。

用法小结

包装类型的==实际比较的是对象的内存地址是否相同,equals()方法比较的是数值是否相等。

用法如下:

  1. 基本类型之间使用==作为相等判断,
  2. 基本类型和包装类型使用==或使用包装类型的equals()方法做相等判断
  3. 包装类型之间使用equals()方法做相等判断

版权声明:著作权归作者所有。

相关推荐

JavaScript判断两个数组是否相等

首先判断两个数组是否相等时不能直接使用==var array1 = []; var array2 = []; console.log(array1 == array2); //输出false 对于对象来说,==比较的是两个对象是否为同一个对象。数组属于对象类型,尽管数组元素是相同的,但这两个数组属于不同的对象

Python:有关IntEnum类型的比较

枚举类型的使用请参考:Python3.4 枚举类型的使用。我们在使用Enum定义枚举类型,枚举的成员不是整型,所以在做比较时不能使用如大于号(">"),小于号(“<”)作比较。只用做相等性比较。但直接和整型做相等比较,结果都为False。Python新增了IntEnum,IntEnum是允许和整型做比较,包括大小比较和值得相等比较。创建IntEnum定义I

Kotlin:基本类型 - 数值

内置数值类型Kotlin和Java的数值类型很接近,内置了6中数值类型:Double:64 Float:32 Long:64 Int:32 Short:16 Byte:8 在Java里,char类型也是一种数值类型,可以和其他数值类型转换,而在Kotlin则没有把char类型作为数值类型。字面量整数整数类型:Shot,Int和Long。和Java一样,Long类型的字面量在数字后面加上L来表示。&

Java Objects.hash()与自己实现的hashCode()比较

Java 7新增了Objects类,它为对象提供了一些便捷的静态方法,如equals(),hashCode(),hash(),compare(),toString()等等。这里比较一下Objects.hash()与自己实现的hashCode()。传统实现的hashCode@Override public int hashCode() {  &nbs

TypeScript:基本类型详解

布尔值(Boolean)TypeScript的布尔值和JavaScript一样有两个值:true和false。类型标识:boolean示例:let isDone: boolean = false; 数字(Number)和JavaScript一样,TypeScript的所有数字都是用浮点数表示,支持二进制,八进制,十进制以及十六进制的表示方式,类型标识:num