zoukankan      html  css  js  c++  java
  • 2)Java中的==和equals

    Java中的==和equals
     
    1.如果比较对象是值变量:只用==
     
    2.如果比较对象是引用型变量:
         ==:比较两个引用是不是指向同一个对象实例。
         equals:
                首先Object类中equals的实现是直接调用了==操作。
                一个自定义类继承自Object且没有重写equals方法,那么其equals操作也是与Object类一样,仅仅是直接调用==操作。
                如果一个类重写过equals方法(或者继承自一个重写过equals方法的类),那么效果与==操作不同
        
         如果是你自己定义的一个类,比较自定义类用equals和==是一样的,都是比较句柄地址, 因为自定义的类是继承于object,而object中的equals就是用==来实现的。
     
    检查两个引用型变量是否属于同一个Class:instanceof
              System.out.println((obj1 instanceof Student) && (obj2 instanceof Student)) 
     
     
    API里的类大部分都重写了equals方法。例如String类

     
    1>String类型的比较
           ==:比较两个str是否是指向同一个对象实例。
           equals:比较两个str中的内容是否相同
     
         对String的比较来说,还存在public String intern()方法。
         当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。
         它遵循对于任何两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。
     
    1 String a = new String("ab");
    2 String b = new String("ab");
    3 String c = "ab";
    4 String d = "a" + "b";
    5 String e = "b";
    6 String f = "a" + e;
    8 System.out.println(b.intern() == a);
    9 System.out.println(b.intern() == c);
    10 System.out.println(b.intern() == d);
    11 System.out.println(b.intern() == f);
    12 System.out.println(b.intern() == a.intern());
     

     

    运行结果:false  true  true  false  true

    由运行结果可以看出来,b.intern() == a和b.intern() == c可知
    采用new 创建的字符串对象不进入字符串池,
    字符串相加的时候,都是静态字符串的结果会添加到字符串池,如果其中含有变量(如f中的e)则不会进入字符串池中。
    在定义变量的时候赋值,如果赋值的是静态的字符串,就会执行进入字符串缓冲池的操作,如果池中含有该字符串,则返回引用。
     
     


    2>数据类型封装类的比较
     
    Java为每一个简单数据类型提供了一个封装类,每个基本数据类型可以封装成对象类型。 除int(Integer)和char(Character),其余类型首字母大写即成封装类类型名。double (Double), float(Float),long(Long), short(Short),byte(Byte),boolean(Boolean).
      
    以int和Integer为例说明  Java中int和Integer区别如下:
         1.int是基本的数据类型,默认值可以为0;Integer是int的封装类,默认值为null;
         2.int和Integer都可以表示某一个数值,但int和Integer不能够互用,因为他们两种不同的数据类型;
    int a1=1;
    int a2=1;
    Integer b1 =new Integer (1);
    Integer b2 =new Integer (1);
    Answer:
    a1==a2 这个是成立的,很简单,都知道
    a1==b1 这个是不成立的.表达式的值为 false ,它们是不同的数据类型(在jdk1.5以上版本中为true)
    b1==b2 这个也是不成立的.表达式的值为 false,虽然是相同的数据类型,但是它们是两个对象,==比较的是2个对象的地址,它们的地址是不相等的,内容相等都是1;
    b1.equals(b2)==true 这个是成立的,表达式的值为 true. 相同数据类型,两个对象,地址不同,内容相同, quals比较的是2个对象的内容,所以成立。
    (a.equals(b),因为equals比较的是两个对象,所以a,b都不能为基本数据类型,否则会出编译错误。)(在jdk1.5以上版本中,b可以为基本数据类型,a不可以) 同理,其它的封装类和基本类型也是这样

    在jdk1.5以上的版本中,基本类型和封装类能自动转化,与String类型的对象和字符串常量类似。
            Integer i1 = 123;        
            Integer i2 = 123;
            int i = 123;         
            Integer i3 = new Integer(123);         Integer i4 = new Integer(123);                        
            System.out.println("i1 == i2 = "+(i1 == i2));
            System.out.println("i1.equals(i2) = "+(i1.equals(i2)));         
            System.out.println();
            System.out.println("i3 == i4 = "+(i3 == i4));
            System.out.println("i3.equals(i4) = "+(i3.equals(i4)));         
            System.out.println();
            System.out.println("i2 == i4 = "+(i2 == i4));
            System.out.println("i2.equals(i4) = "+(i2.equals(i4)));         
            System.out.println();
            System.out.println("i == i2 = "+(i == i2));
            System.out.println("i1.equals(i) = "+(i1.equals(i)));         
            System.out.println();
            System.out.println("i == i4 = "+(i == i4));
            System.out.println("i4.equals(i) = "+(i4.equals(i)));        
    Answer:      
             i1 == i2 = true      
             i1.equals(i2) = true     
             i3 == i4 = false      
             i3.equals(i4) = true      
             i2 == i4 = false      
             i2.equals(i4) = true      
             i == i2 = true      
             i1.equals(i) = true      
             i == i4 = true    
             i4.equals(i) = true 
     

     
    3>对象的hashcode和equals
     
    1)理解hashcode的作用
         以java.lang.Object来理解,JVM每new一个Object,它都会将这个Object丢到一个Hash哈希表中去。下次做Object的比较或者取这个对象的时候,它会根据对象的hashcode再从Hash表中取这个对象。这样做的目的是提高取对象的效率。具体过程是这样:
    1.new Object(),JVM根据这个对象的Hashcode值,放入到对应的Hash表对应的Key上,如果发生了Hash key相同导致冲突的情况,那么就在这个Hash key的地方产生一个链表,将所有产生相同hashcode的对象放到这个单链表上去。
    2.比较两个对象的时候,首先根据他们的hashcode去hash表中找他的对象,当两个对象的hashcode相同,那么就是说他们这两个对象放在Hash表中的同一个key上,那么他们一定在这个key上的链表上。那么此时就只能根据Object的equal方法来比较这个对象是否equal。当两个对象的hashcode不同的话,肯定他们不能equal.

    两个相等对象的equals方法一定为true, 但两个hashcode相等的对象不一定是相等的对象。
     
    2)覆盖equals的时候总是要覆盖hashcode
         如果不覆盖hashcode的时候,可能会出现这样的情况,两个对象覆盖之后的equals方法返回为true,但其hashcode方法返回为false,而执行中的优化过程是,调用equals方法之前会先比较两个对象的hash值,如果不同,就不会进行equals比较了。所以覆盖equals方法而不覆盖hashcode方法存在上述风险,比较本应该放回equals的true但是在预执行hash值比较时就返回了false。
    不积跬步无以至千里,不积小流无以成江海。业精于勤而荒于嬉,行成于思而毁于随
  • 相关阅读:
    【BZOJ3995】[SDOI2015]道路修建 线段树区间合并
    [Noip2016]天天爱跑步 LCA+DFS
    【BZOJ2870】最长道路tree 点分治+树状数组
    【BZOJ3730】震波 动态树分治+线段树
    【BZOJ2969】矩形粉刷 概率+容斥
    【BZOJ3029】守卫者的挑战 概率+背包
    【BZOJ3043】IncDec Sequence 乱搞
    【BZOJ3124】[Sdoi2013]直径 树形DP(不用结论)
    Django学习笔记之ORM多表操作
    SQL学习笔记之项目中常用的19条MySQL优化
  • 原文地址:https://www.cnblogs.com/weilf/p/4103941.html
Copyright © 2011-2022 走看看