zoukankan      html  css  js  c++  java
  • JAVA中用堆和栈的概念来理解equals() "=="和hashcode()

    在学习java基本数据类型和复杂数据类型的时候,特别是equals()"=="和hashcode()部分时,不是很懂,也停留了很长时间,最后终于有点眉目了。

    要理解equals()"=="和hashcode(),最好先了解Java内存中堆和栈的知识:

    下面一段是参考自http://www.cnblogs.com/whgw/archive/2011/09/29/2194997.html

    大家也可点进去查看更详细的解释。

    Java 中的堆和栈 

      Java把内存划分成两种:一种是栈内存,一种是堆内存。 

      1、在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。例如:

    int a =10;
    String str;

    这些都是在栈中分配内存。   

      2、义数组和类时都在函数的堆内存中分配。例如:

    String str =new String();
    int []num=int [2]{2,3};
    

      这些都是在堆中分配内存。堆内存用来存放由new创建的对象和数组。 

    Java中栈内存和堆内存的优缺点:

    Java的栈是一个静态数据区,在程序编译时边分配空间。

    Java的堆是一个运行时数据区,类的对象以及数组从中分配空间。这些对象通过new指令建立,它们不需要程序代码来显式的释放。JVM虚拟机中存在垃圾回收机制,堆就是由垃圾回收机制来负责的。

    堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。 

    栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量(int, short, long, byte, float, double, boolean, char)和对象句柄。

    栈有一个很重要的性质,就是存在栈中的数据可以共享。例如:

    int a =5;
    int b =5;

    a和b都是在栈中分配内存的

    程序先给a分配内存,并存入5

    程序给b分配内存时,先检查内存中是否存在5,

    发现存在5,直接把b指向内存中存储5所在的地址。

    即实现了数据的共享性,不可重复性。

    如果后面再加一句:

    int a =5;
    int b =5;
    b = 4;

    前两句执行情况和前面相同,

    第三句时,由于该函数的栈内存中没有存入4,

    故会重新为b分配内存,并存入4

    用堆和栈的概念来理解equals() "=="和hashcode()

    1、对于(int, short, long, byte, float, double, boolean, char)基本数据类型,比较其是否指向同一个对象时用"=="

    double a = 2.5;
    double b = 2.5;
    System.out.println(a==b);

    结果是: true

    原因:对于double基本数据类型,其内存是在栈中分配的,由于栈内存的可共享性,故a,b指向同一个内存空间,及同一个对象。

        而"=="的作用是比较两个变量是否指向同一个对象,故此处为true

    2、对于类,数组等复杂数据类型时,比较其内容是否相等时用equals()和hashcode()

            String string = new String("hello");
            String string2 = new String("hello");
            System.out.println(string.hashCode());
            System.out.println(string2.hashCode());
            System.out.println(string.equals(string2));
            System.out.println(string == string2);    

    结果是:

    99162322
    99162322
    true
    false

    原因:

    对于String,Integer等用类封装的数据类型,其有hashcode()方法。

    hashcode()其实就是对其内容进行某种算法,最后得出一个数值(可能不是这样)。

    所以说,内容一样,hash值一样。

    对于String,Integer等用类封装的数据类型,同样有equals()方法,其作用于”==“相同,用于判断引用类型是否指向同一个对象。

    但是

    当用equals()方法进行比较时,对类File、String、Date及封装类(Wrapper Class)来说,是比较类型及内容而不考虑引用的是否是同一个对象;

    原因:在这些类中覆盖了equals()方法,用于比较内容是否相同。

    所以此处虽然不是同一个对象,但是equals()方法仍然返回true

    此处因为string和string2都属于复杂数据类型,所以其内存都是在堆中分配的,

    而堆中所存储的数据可以重复,故string和string2所指向的不是同一个对象,

    所以 string == string2的结果是false


     

  • 相关阅读:
    .NET泛型中的协变与逆变
    使用 Roslyn引擎动态编译代码
    Windows 自动更新服务恢复
    She Left Her Shoes
    .NET Core 配置
    EFCore中SQLSERVER 2008 的分页问题
    SQL SERVER 2012/ 2014 分页,用 OFFSET,FETCH NEXT改写ROW_NUMBER的用法(转)
    TFS命令行操作
    负载均衡(Load Balancing)学习笔记(三)
    负载均衡(Load Balancing)学习笔记(二)
  • 原文地址:https://www.cnblogs.com/beiyan/p/4232270.html
Copyright © 2011-2022 走看看