了解Java 哈希码(HashCode),理解 == 和 equals(),String创建在内存中的分配

/**
 * 哈希码是可以根据的自己的需求,采用不同的算法产生的一个Int型数字。
 * Object的hashCode()方法返回的哈希码是根据对象的内存地址来生成的,
 * 所以每个对象的哈希码是不相同的
 *
 */
public class Test1 {
    public static void main(String[] args) {
        /**
         * Integer类,返回的哈希码就是Integer对象里所包含的那个整数的数值,
         * 例如Integer i1=new Integer(100),i1.hashCode的值就是100 。
         * 由此可见,2个一样大小的Integer对象,返回的哈希码也一样。
         *
         */
        Integer i = 100;
        Integer j = 100;
        System.out.println("i的hashcode:" + i.toString());
        System.out.println("j的hashcode:" + j.toString());
        /**
         * String类的hashCode.String类重写了Object中的hashCode方法
         * 根据String类包含的字符串的内容,
         * 根据一种特殊算法返回哈希码,只要字符串内容相同,
         * 返回的哈希码也相同。
         */
        String a = "12345hahaha";
        String b = "12345hahaha";
        String c = new String("12345hahaha");
        System.out.println("a的hashcode:" + a.hashCode());
        System.out.println("b的hashcode:" + b.hashCode());
        System.out.println("c的hashcode:" + c.hashCode());
        /**
         *  == :
         *  1.判断是否指向堆内存的同一块内存地址
         *  2.基本数据类型的比较
         */
        if (a == b) {
            System.out.println("a = b");
        }
        if(a == c) {
            System.out.println("a = c");
        }else {
            System.out.println("a != c");
        }
        /**
         * Object中toString()方法的实输出格式是这样的
         * getClass().getName() + “@” + Integer.toHexString(hashCode())
         * Object类的hashCode.返回对象的内存地址经过处理后的结构,
         * 由于每个对象的内存地址都不一样,所以哈希码也不一样。
         *
         */
        People people1 = new People();
        people1.setName("chisaki");
        System.out.println("people1的hashcode:" + people1.hashCode());
        System.out.println("直接输出people1对象:" + people1.toString());
        People people2 = new People();
        people2.setName("chisaki");
        System.out.println("people2的hashcode:" + people2.hashCode());
        System.out.println("直接输出people2对象:" + people2.toString());
        if (people1 == people2) {
            System.out.println("people1 = people2");
        } else {
            System.out.println("people1 != people2");
        }

    }
}

运行结果:

i的hashcode:100
j的hashcode:100
a的hashcode:-2077788642
b的hashcode:-2077788642
c的hashcode:-2077788642
a = b
a != c
people1的hashcode:1735600054
直接输出people1对象:People@677327b6
people2的hashcode:21685669
直接输出people2对象:People@14ae5a5
people1 != people2

结论:a = b  a != c

了解Java 哈希码(HashCode),理解 == 和 equals(),String创建在内存中的分配_第1张图片
图片来源:http://www.cnblogs.com/smyhvae/p/3929585.html

下面截取自:https://blog.csdn.net/qq_33417486/article/details/82787598 
String str1= “abc”; 在编译期,JVM会去常量池来查找是否存在“abc”,如果不存在,就在常量池中开辟一个空间来存储“abc”;如果存在,就不用新开辟空间。然后在栈内存中开辟一个名字为str1的空间,来存储“abc”在常量池中的地址值。

String str2 = new String("abc") ;在编译阶段JVM先去常量池中查找是否存在“abc”,如果过不存在,则在常量池中开辟一个空间存储“abc”。在运行时期,通过String类的构造器在堆内存中new了一个空间,然后将String池中的“abc”复制一份存放到该堆空间中,在栈中开辟名字为str2的空间,存放堆中new出来的这个String对象的地址值。

也就是说,前者在初始化的时候可能创建了一个对象,也可能一个对象也没有创建;后者因为new关键字,至少在内存中创建了一个对象(堆内存中的对象),也有可能是两个对象(如果常量池中没有“abc”,就创建一个常量池中的对象)。


 

你可能感兴趣的:(Java,基础)