zoukankan      html  css  js  c++  java
  • Integer类型比较杂谈

    Integer类型的比较是面试中常问的一个东西, 如果深入了解其中也大有学问, 涉及基本数据类型,引用数据类型的装箱拆箱,类加载机制等,

    首先看下面两段代码的执行结果

    public static void IntegerDemo1() {
                Integer i1 = 100;
                Integer i2 = 100;
                System.out.println(i1.hashCode());
                System.out.println(i2.hashCode());
                System.out.println("比较结果:" + (i1 == i2));
                System.out.println("比较结果:" + i1.equals(i2));
                System.out.println("比较结果:" + i1.compareTo(i2));
            }
        100
        100
        比较结果:true
        比较结果:true
        比较结果:0
    public static void IntegerDemo1() {
                Integer i1 = 200;
                Integer i2 = 200;
                System.out.println(i1.hashCode());
                System.out.println(i2.hashCode());
                System.out.println("比较结果:" + (i1 == i2));
                System.out.println("比较结果:" + i1.equals(i2));
                System.out.println("比较结果:" + i1.compareTo(i2));
            }
       200
        200
        比较结果:false
        比较结果:true
        比较结果:0    

    为什么变量是100和200时会出现上述的结果呢?

    首先要明白Integer i1 = 100做了什么? 在做这样的操作时,实际就是基本数据类型与引用类型之间的拆箱和装箱操作,Integer i1 = 100是一个装箱操作,
    本质就是Integer i1 = Integer.valueOf(100),源码如下,

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

    在valueOf方法,,对赋的值进行一个判断操作,如果值在-128~127之间,就会在内部类IntegerCache的cache[]数组中获取一个Integer对象,
    如果不是就new一个新的Integer对象.

    那么cache[]中又是什么呢?

     cache = new Integer[(high - low) + 1];
     int j = low;
     for(int k = 0; k < cache.length; k++)
         cache[k] = new Integer(j++);

    从IntegerCache中的一段源码中可以发现cache[]中循环放入了值在-128~127之间的Integer对象,根据内部类加载机制,当类第一次
    调用时会初始化这个数组,并且在JVM中只初始化一次,到这里我们就明白了为什么赋值在-128~127之间的比较时能够相等,
    因为==比较的是内存地址,示例代码中的变量i1和i2在这个范围内都引用了从cache取出的同一个对象,对象内存地址一样,
    所以是相等的,在超出这个范围之后,每次创建会new一个新的Integer对象,引用的是不同的对象,所以不相等.

    那为什么equals方法一直相等呢?

    public boolean equals(Object obj) {
            if (obj instanceof Integer) {
                return value == ((Integer)obj).intValue();
            }
            return false;
    }

    可以看到Integer对equals方法进行重写,从比较两个对象的内存地址变成了比较两个Integer对象的的值,这与String类相似,

    同时重写的还有hashCode()方法,hashcode返回了对象的值.

    那为什么要设计IntegerCache类来缓存-128~127的对象呢?

    节省内存消耗,提高程序性能,Integer是一个经常使用到的类,并且一般创建的对象值范围都在-128~127之间,
    并且创建这样相似值的对象并没有太大意义,所以使用IntegerCache类,与此类似的ByteCache、ShortCache等.

    那Integer比较用什么方法呢?

    推荐compareTo方法,其次equals方法

  • 相关阅读:
    go调查内存泄漏
    c++ 使用模板按类型统计stl多维容器中元素的数量
    phxpaxos遇到反复拉取checkpoint但是反复失败的问题,给其它节点造成压力
    phxpaxos实现状态机CAS操作
    使用phxpaxos开发过程中遇到的坑
    std::condition_variable::wait_until segment
    c++ protected 访问限定
    c++多态
    IO多路复用的水平触发与边缘触发
    Redis 源码分析系列1-main函数相关调用分析
  • 原文地址:https://www.cnblogs.com/zhexuejun/p/13157930.html
Copyright © 2011-2022 走看看