文档章节

"=="和equals方法究竟有什么区别

TimApache
 TimApache
发布于 2016/05/11 15:34
字数 1484
阅读 5
收藏 0

总结两个东西的时候,先单独把一个东西说明白了,然后说清楚另外一个。在单个描述的时候可以根据自己使用的心得把要注意的地方可以同时说出来。

==  操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用==操作符。

如果一个变量指向的数据是对象类型的,那么,这时候涉及了两块内存,对象本身占用一块内存(堆内存),变量也占用一块内存,例如Objet obj = new Object();变量obj是一个内存,new Object()是另一个内存,此时,变量obj所对应的内存中存储的数值就是对象占用的那块内存的首地址。对于指向对象类型的变量,如果要比较两个变量是否指向同一个对象,即要看这两个变量所对应的内存中的数值是否相等,这时候就需要用==操作符进行比较。

 

equals 方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的。例如,对于下面的代码:

String a=new String("foo");

String b=new String("foo");

两条new语句创建了两个对象,然后用a,b这两个变量分别指向了其中一个对象,这是两个不同的对象,它们的首地址是不同的,即a和b中存储的数值是不相同的,所以,表达式a==b将返回false,而这两个对象中的内容是相同的,所以,表达式a.equals(b)将返回true。

在实际开发中,我们经常要比较传递进行来的字符串内容是否等,例如,String input = …;input.equals(“quit”),许多人稍不注意就使用==进行比较了,这是错误的,随便从网上找几个项目实战的教学视频看看,里面就有大量这样的错误。记住,字符串的比较基本上都是使用equals方法。

如果一个类没有自己定义equals方法,那么它将继承Object类的equals方法,Object类的equals方法的实现代码如下:

boolean equals(Object o){

return this==o;

}

这说明,如果一个类没有自己定义equals方法,它默认的equals方法(从Object 类继承的)就是使用==操作符,也是在比较两个变量指向的对象是否是同一对象,这时候使用equals和使用==会得到同样的结果,如果比较的是两个独立的对象则总返回false。如果你编写的类希望能够比较该类创建的两个实例对象的内容是否相同,那么你必须覆盖equals方法,由你自己写代码来决定在什么情况即可认为两个对象的内容是相同的。

然而对于equels的重写应该注意一下几点:

package com.ch.test;

import java.util.Date;

public class MainTest {
     
     private String name;
     private Date birthday;
     
     public MainTest(){}
     
     public String getName() {
      return name;
     }

     public void setName(String name) {
      this.name = name;
     }

     public Date getBirthday() {
      return birthday;
     }

     public void setBirthday(Date birthday) {
      this.birthday = birthday;
     }
     
     /*
      * 重写equals必须注意:
      * 1 自反性:对于任意的引用值x,x.equals(x)一定为true
      * 2  对称性:对于任意的引用值x 和 y,当x.equals(y)返回true,y.equals(x)也一定返回true
      * 3 传递性:对于任意的引用值x、y和z,如果x.equals(y)返回true,并且y.equals(z)也返回true,
      *  那么x.equals(z)也一定返   回 true
      * 4 一致性:对于任意的引用值x 和 y,如果用于equals比较的对象信息没有被修改,
      *  多次调用x.equals(y)要么一致地返回true,要么一致地返回false
      * 5 非空性:对于任意的非空引用值x,x.equals(null)一定返回false
      * 
      * 请注意:
      * 重写equals方法后最好重写hashCode方法,否则两个等价对象可能得到不同的hashCode,这在集合框架中使用可能产生严重后果
      */
     
     
     /*
      *  1.重写equals方法修饰符必须是public,因为是重写的Object的方法.
      *  2.参数类型必须是Object.
      */
     public boolean equals(Object other){       
      //重写equals方法,后面最好重写hashCode方法
      if(this == other)                                      
      //先检查是否其自反性,后比较other是否为空。这样效率高
       return true;
      if(other == null)        
       return false;
      if( !(other instanceof MainTest))
       return false;
     
      final MainTest MainTest = (MainTest)other;
     
      
      if( !getName().equals(MainTest.getName()))
       return false;
      if( !getBirthday().equals(MainTest.getBirthday()))
       return false;
      
      return true;
     }
     
     public int hashCode(){                 
     //hashCode主要是用来提高hash系统的查询效率。当hashCode中不进行任何操作时,
     //可以直接让其返回 一常数,或者不进行重写。
      int result = getName().hashCode();
      result = 29 * result +getBirthday().hashCode();
      return result;
     }

     public static void main(String[] args) { 
     
      Date dayA = new Date(4000000); 
      MainTest a = new MainTest();
      a.setName("a");
      a.setBirthday(dayA);
     
      Date dayB = new Date(1000000);
      MainTest b = new MainTest();
      b.setName("a");
      b.setBirthday(dayB);
     
      Date dayC = dayA;
      MainTest c = new MainTest();
      c.setName("a");
      c.setBirthday(dayC);
     
      Date dayE = dayA;
      MainTest e = new MainTest();
      e.setName(a.getName());
      e.setBirthday(a.getBirthday());
     
      Date dayD = dayC;
      TestEquel d = new TestEquel();
      d.setName("a");
      d.setBirthday(dayD);
     
      System.out.println(a.equals(b));     //调用自己类中所定义的equals方法
      System.out.println(a.equals(a));
      System.out.println(a.equals(c));
     
      System.out.println(d.equals(a));
      System.out.println(a.equals(d));      //验证重写equals的对称性
      System.out.println(a.equals(e));
      System.out.println(e.equals(c));      //验证重写equals的传递性
      System.out.println(d.getName().equals(a.getName()));   //调用Object类中equals方法
      System.out.println(d.getBirthday().equals(b.getBirthday()));
     
      System.out.println("比较hanshCode的值");
     
      /*
       *    * 比较hashCode方法中返回的值
       * 如果equals返回为true,则hashCode一定返回true。
       * 如果equals返回为false,hashCode返回值不一定不相同。
       * 如果hashCode返回值不同,则equals返回值一定为false。
       * 如果hashCode返回值不同,则equals返回值不一定为false。
       */
      System.out.println(a.hashCode());
      System.out.println(b.hashCode());
      //如果equals返回false,则各hashCode不一定返回不同值
      System.out.println(a.hashCode()== b.hashCode());    
      System.out.println(a.hashCode() == c.hashCode());   
           
     } 
}

 

 

 

 

本文转载自:http://www.cnblogs.com/NF-CHH/archive/2012/12/16/equals.html

共有 人打赏支持
上一篇: Java之JSON&XML转换
下一篇: JAVA工具_PinyinConv
TimApache
粉丝 1
博文 24
码字总数 591
作品 0
珠海
程序员
私信 提问
笔试题之Java基础部分【简】【二】

1.静态变量和实例变量的区别 2.Integer与int的区别 3.是否可以从一个static方法内部发出对非static方法的调用 4.内部类可以引用它的包含类的成员吗?有没有什么限制 5.使用final关键字修饰一...

anlve
2018/06/18
0
0
程序员有什么办法能快速梳理java知识点?有这八张图就够了

一图胜千言,下面图解均来自Program Creek 网站的Java教程,目前它们拥有最多的票选。如果图解没有阐明问题,那么你可以借助它的标题来一窥究竟。 1、字符串不变性 下面这张图展示了这段代码...

java进阶架构师
2017/11/15
0
0
Java基础----浅谈Java中的equals和==

浅谈Java中的equals和== 1.先上案例: 运行后打印情况: 为什么这两者打印的情况会不同,今天我们就带着这个问题来看一下equals()与“==”到底有什么区别? 2.关系操作符“==”到底比较的是...

android-key
2016/12/11
2
0
浅谈Java中的equals和==

在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello");2 String str2 = new String("hello");3 4 System.out.println(str1==str2);5 System.out.println(str1.equ......

小车车
2016/12/19
1
0
java基础:==和equals方法区别

equals()和“==”操作用于对象的比较,检查俩对象的相等性,但是他们俩的主要区别在于前者是方法后者是操作符。由于java不支持操作符重载(overloading),“==”的行为对于每个对象来说与equ...

watermelon11
02/23
0
0

没有更多内容

加载失败,请刷新页面

加载更多

glide 下载golang.org包问题

今天编译Uber的Aresgo。依赖管理用 glide,下载golang.org 包的时候遇到问题。 方法一: 设置 glide mirror glide mirror set https://golang.org/x/mobile https://github.com/golang/mobi...

shengjuntu
7分钟前
0
0
4.线程

线程是操作系统中最小的执行单元。 它本身不是一个程序,而是在程序中运行。 换句话说,线程并不相互独立,并与其他线程共享代码段,数据段等。 这些线程也被称为轻量级进程。 线程状态 新线...

Eappo_Geng
14分钟前
0
0
在Linux上编译LLVM/Clang 8.0.0等全部源代码

本教程使用的操作系统是Ubuntu Linux 18.04.2 LTS版本,要编译的LLVM源代码是8.0.0。 1、安装必要的软件。它们是:build-essential/cmake/swig/python-swigpk/libxml2/libxml2-dev/libncurs...

ryanliue
22分钟前
1
0
毕业季,我的Linux求职之路

秋招终于告一段落了,本硕的七年求学之路也快画上了句号。回首求职的这一段日子,痛苦并快乐着。感谢所有陪伴着我走过这一段路程的同学,所有的辛酸都值得铭记。求职的过程中在网上看了很多的...

linux-tao
52分钟前
3
0
Mybatis动态语句,if test字符串不用进行null判断

描述:根据creator列进行过滤获取image表的数据。 代码如下: @Select("<script>" + " select * from image " + " <where>" + " <if test='isAllCreator != 1'> ......

Coder顾
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部