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。
    不积跬步无以至千里,不积小流无以成江海。业精于勤而荒于嬉,行成于思而毁于随
  • 相关阅读:
    973. K Closest Points to Origin
    919. Complete Binary Tree Inserter
    993. Cousins in Binary Tree
    20. Valid Parentheses
    141. Linked List Cycle
    912. Sort an Array
    各种排序方法总结
    509. Fibonacci Number
    374. Guess Number Higher or Lower
    238. Product of Array Except Self java solutions
  • 原文地址:https://www.cnblogs.com/weilf/p/4103941.html
Copyright © 2011-2022 走看看