最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中判斷對象是否相等的equals()方法使用教程

 更新時間:2016年05月26日 08:59:21   作者:xiongchao2011  
與==運算符響應(yīng),equals()方法也是Java中對對象進行比較的一大方式,要特別注意二者的不同點,這個我們在下文中即將講到,接下來我們就來看一下Java中判斷對象是否相等的equals()方法使用教程

Object類中的equals方法用于檢測一個對象是否等于另一個對象。在Object類中,這個方法判斷兩個對象是否具有相同的引用,如果兩個對象具有相同的引用,它們一定是相等的。從這點上看,將其作為默認操作也是合乎情理的。然而,對于多數(shù)類類說,這種判斷并沒有什么意義,例如,采用這種方式比較兩個PrintStream是否相等就完全沒有意義。然而,經(jīng)常需要檢測兩個對象狀態(tài)的相等性,如果兩個對象的狀態(tài)相等,就認為這兩個對象是相等的。所以一般在自定義類中都要重寫equals比較。

下面給出編寫一個完美equals()方法的建議:

(1)顯式參數(shù)命名為otherObject,稍后需要將轉(zhuǎn)換成一個叫other的變量

(2)檢測this與otherObject是否引用同一個對象:

if(this==otherObject) return true;

這條語句只是一個優(yōu)化。實際上,這是一種經(jīng)常采用的形式。因為計算這個等式要比一個一個地比較類中的域所付出的代價小的多。

(3)檢測otherObject是否為null,如果為null,返回false。這項檢測是很必要的。

if(otherObject==null) return false;

(4)比較this和otherObject是否屬于同一個類,如果equals的語義在每個子類中有所改變,就使用getClass()檢測,它將自己作為目標類

if(getClass()!=otherObject.getClass()) return false;

如果所有的子類都擁有同一的語義,就使用instanceof檢測

if(!(otherObject instanceof ClassName)) return false;

(5)將otherObject轉(zhuǎn)換為相應(yīng)類型的變量:

ClassName other=(ClassName)otherObject;

(6)現(xiàn)在開始對所有需要比較的域進行比較。使用==比較基本類型域,使用equals比較對象域。如果所有域都匹配,就返回true,否則返回false;

return field1==other.field1&&field2.equals(other.field2)

如果在子類中重新定義equals,就要在其中包含調(diào)用super.equals(other)。如果檢測失敗,就不可能相等。如果超類中的域相等,就比較子類中的實例域。

對于數(shù)組類型的域,可以使用靜態(tài)的Arrays.equals方法檢測相應(yīng)的元素是否相等。

來看幾個字符串比較例子:

String a = "abc"; 
String b = "abc"; 
String c = new String("abc"); 
String d = new String("abc"); 
System.out.println(a == b); // true 因為JAVA中字符串常量是共享的,只有一個拷貝 
System.out.println(a == c); // false a和c屬于2個不同的對象 
System.out.println(a.equals(c)); // true 由于String對象的equals方法比較的是對象中的值,所以返回true。(和Object的equals方法不同) 
System.out.println(c==d); // false c和d雖然對象內(nèi)的值相同,但屬于2個不同的對象,所以不相等 
System.out.println(c.equals(d)); // true 

簡單的說,當比較字符串常量時,等于和equals返回的結(jié)果一樣,當想比較字符串對象的值時用equals。

看一個equals的使用例子:

package chapter05.EqualsTest; 
 
import java.util.*; 
 
public class EqualsTest { 
 public static void main(String[] args) { 
  Employee alice1 = new Employee("Alice Adams", 75000, 1987, 12, 15); 
  Employee alice2 = alice1; // reference the same object 
  Employee alice3 = new Employee("Alice Adams", 75000, 1987, 12, 15); 
  Employee bob = new Employee("Bob Brandson", 50000, 1989, 10, 1); 
 
  System.out.println("alice1 == alice2: " + (alice1 == alice2)); 
 
  System.out.println("alice1 == alice3: " + (alice1 == alice3)); 
 
  System.out.println("alice1.equals(alice3): " + (alice1.equals(alice3))); 
 
  System.out.println("alice1.equals(bob): " + (alice1.equals(bob))); 
 
  System.out.println(bob.toString()); 
 } 
} 
 
class Employee { 
 public Employee(String n, double s, int year, int month, int day) { 
  name = n; 
  salary = s; 
  GregorianCalendar calendar = new GregorianCalendar(year, month, day); 
  hireDay = calendar.getTime(); 
 } 
 
 public String getName() { 
  return name; 
 } 
 
 public double getSalary() { 
  return salary; 
 } 
 
 public Date getHireDay() { 
  return hireDay; 
 } 
 
 public void raiseSalary(double byPercent) { 
  double raise = salary * byPercent / 100; 
  salary += raise; 
 } 
 
 @Override 
 public boolean equals(Object otherObject) { 
  // a quick test to see if the objects are identical 
  if (this == otherObject) 
   return true; 
 
  // must return false if the explicit parameter is null 
  if (otherObject == null) 
   return false; 
 
  // if the classed don't match,they can't be equal 
  if (getClass() != otherObject.getClass()) 
   return false; 
 
  // now we know otherObject is a non-null Employee 
  Employee other = (Employee) otherObject; 
 
  // test whether the fields hava identical values 
  return name.equals(other.name) && salary == other.salary 
    && hireDay.equals(other.hireDay); 
 
 } 
 
 @Override 
 public int hashCode() { 
  return 7 * name.hashCode() + 11 * new Double(salary).hashCode() + 13 
    * hireDay.hashCode(); 
 } 
 
 @Override 
 public String toString() { 
  return getClass().getName() + "[name=" + name + ",salary=" + salary 
    + ",hireDay=" + hireDay + "]"; 
 } 
 
 private String name; 
 private double salary; 
 private Date hireDay; 
} 
 
class Manager extends Employee { 
 public Manager(String n, double s, int year, int month, int day) { 
  super(n, s, year, month, day); 
  bouns = 0; 
 } 
 
 @Override 
 public double getSalary() { 
  double baseSalary = super.getSalary(); 
  return baseSalary + bouns; 
 } 
 
 public void setBouns(double b) { 
  bouns = b; 
 } 
 
 @Override 
 public boolean equals(Object otherObject) { 
  if (!super.equals(otherObject)) 
   return false; 
  Manager other = (Manager) otherObject; 
  // super equals checked that this and other belong to the same class 
  return bouns == other.bouns; 
 } 
 
 @Override 
 public int hashCode() { 
  return super.hashCode() + 17 * new Double(bouns).hashCode(); 
 } 
 
 @Override 
 public String toString() { 
  return super.toString() + "[bouns=" + bouns + "]"; 
 } 
 
 private double bouns; 
} 

深入
下面根據(jù)“類是否覆蓋equals()方法”,將它分為2類。
(1) 若某個類沒有覆蓋equals()方法,當它的通過equals()比較兩個對象時,實際上是比較兩個對象是不是同一個對象。這時,等價于通過“==”去比較這兩個對象。
(2) 我們可以覆蓋類的equals()方法,來讓equals()通過其它方式比較兩個對象是否相等。通常的做法是:若兩個對象的內(nèi)容相等,則equals()方法返回true;否則,返回fasle。
下面,舉例對上面的2種情況進行說明。
1. “沒有覆蓋equals()方法”的情況
代碼如下 (EqualsTest1.java):

import java.util.*;
import java.lang.Comparable;

/**
 * @desc equals()的測試程序。

 */
public class EqualsTest1{

 public static void main(String[] args) {
  // 新建2個相同內(nèi)容的Person對象,
  // 再用equals比較它們是否相等
  Person p1 = new Person("eee", 100);
  Person p2 = new Person("eee", 100);
  System.out.printf("%s\n", p1.equals(p2));
 }

 /**
  * @desc Person類。
  */
 private static class Person {
  int age;
  String name;

  public Person(String name, int age) {
   this.name = name;
   this.age = age;
  }

  public String toString() {
   return name + " - " +age;
  }
 }
}

運行結(jié)果:

復(fù)制代碼 代碼如下:
false

結(jié)果分析
我們通過 p1.equals(p2) 來“比較p1和p2是否相等時”。實際上,調(diào)用的Object.java的equals()方法,即調(diào)用的 (p1==p2) 。它是比較“p1和p2是否是同一個對象”。
而由 p1 和 p2 的定義可知,它們雖然內(nèi)容相同;但它們是兩個不同的對象!因此,返回結(jié)果是false。

2. "覆蓋equals()方法"的情況
我們修改上面的EqualsTest1.java:覆蓋equals()方法。
代碼如下 (EqualsTest2.java):

import java.util.*;
import java.lang.Comparable;

/**
 * @desc equals()的測試程序。
 */
public class EqualsTest2{

 public static void main(String[] args) {
  // 新建2個相同內(nèi)容的Person對象,
  // 再用equals比較它們是否相等
  Person p1 = new Person("eee", 100);
  Person p2 = new Person("eee", 100);
  System.out.printf("%s\n", p1.equals(p2));
 }

 /**
  * @desc Person類。
  */
 private static class Person {
  int age;
  String name;

  public Person(String name, int age) {
   this.name = name;
   this.age = age;
  }

  public String toString() {
   return name + " - " +age;
  }

  /** 
   * @desc 覆蓋equals方法 
   */ 
  @Override
  public boolean equals(Object obj){ 
   if(obj == null){ 
    return false; 
   } 

   //如果是同一個對象返回true,反之返回false 
   if(this == obj){ 
    return true; 
   } 

   //判斷是否類型相同 
   if(this.getClass() != obj.getClass()){ 
    return false; 
   } 

   Person person = (Person)obj; 
   return name.equals(person.name) && age==person.age; 
  } 
 }
}

運行結(jié)果:

復(fù)制代碼 代碼如下:
true

結(jié)果分析:
我們在EqualsTest2.java 中重寫了Person的equals()函數(shù):當兩個Person對象的 name 和 age 都相等,則返回true。
因此,運行結(jié)果返回true。
講到這里,順便說一下java對equals()的要求。有以下幾點:
對稱性:如果x.equals(y)返回是"true",那么y.equals(x)也應(yīng)該返回是"true"。
反射性:x.equals(x)必須返回是"true"。
類推性:如果x.equals(y)返回是"true",而且y.equals(z)返回是"true",那么z.equals(x)也應(yīng)該返回是"true"。
一致性:如果x.equals(y)返回是"true",只要x和y內(nèi)容一直不變,不管你重復(fù)x.equals(y)多少次,返回都是"true"。
非空性,x.equals(null),永遠返回是"false";x.equals(和x不同類型的對象)永遠返回是"false"。
現(xiàn)在,再回顧一下equals()的作用:判斷兩個對象是否相等。當我們重寫equals()的時候,可千萬不好將它的作用給改變了!


equals() 與 == 的區(qū)別是什么?
== : 它的作用是判斷兩個對象的地址是不是相等。即,判斷兩個對象是不是同一個對象。
equals() : 它的作用也是判斷兩個對象是否相等。但它一般有兩種使用情況(前面第1部分已詳細介紹過):
     情況1,類沒有覆蓋equals()方法。則通過equals()比較該類的兩個對象時,等價于通過“==”比較這兩個對象。
     情況2,類覆蓋了equals()方法。一般,我們都覆蓋equals()方法來兩個對象的內(nèi)容相等;若它們的內(nèi)容相等,則返回true(即,認為這兩個對象相等)。
下面,通過示例比較它們的區(qū)別。
代碼如下:

import java.util.*;
import java.lang.Comparable;

/**
 * @desc equals()的測試程序。
 */
public class EqualsTest3{

 public static void main(String[] args) {
  // 新建2個相同內(nèi)容的Person對象,
  // 再用equals比較它們是否相等
  Person p1 = new Person("eee", 100);
  Person p2 = new Person("eee", 100);
  System.out.printf("p1.equals(p2) : %s\n", p1.equals(p2));
  System.out.printf("p1==p2 : %s\n", p1==p2);
 }

 /**
  * @desc Person類。
  */
 private static class Person {
  int age;
  String name;

  public Person(String name, int age) {
   this.name = name;
   this.age = age;
  }

  public String toString() {
   return name + " - " +age;
  }

  /** 
   * @desc 覆蓋equals方法 
   */ 
  @Override
  public boolean equals(Object obj){ 
   if(obj == null){ 
    return false; 
   } 

   //如果是同一個對象返回true,反之返回false 
   if(this == obj){ 
    return true; 
   } 

   //判斷是否類型相同 
   if(this.getClass() != obj.getClass()){ 
    return false; 
   } 

   Person person = (Person)obj; 
   return name.equals(person.name) && age==person.age; 
  } 
 }
}

運行結(jié)果:

p1.equals(p2) : true
p1==p2 : false

結(jié)果分析:
在EqualsTest3.java 中:
(1) p1.equals(p2)
這是判斷p1和p2的內(nèi)容是否相等。因為Person覆蓋equals()方法,而這個equals()是用來判斷p1和p2的內(nèi)容是否相等,恰恰p1和p2的內(nèi)容又相等;因此,返回true。
(2) p1==p2
這是判斷p1和p2是否是同一個對象。由于它們是各自新建的兩個Person對象;因此,返回false。

相關(guān)文章

  • Spring Boot配置Thymeleaf(gradle)的簡單使用

    Spring Boot配置Thymeleaf(gradle)的簡單使用

    今天小編就為大家分享一篇關(guān)于Spring Boot配置Thymeleaf(gradle)的簡單使用,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • 深入淺出講解Java8函數(shù)式編程

    深入淺出講解Java8函數(shù)式編程

    不管是前端還是后端開發(fā)人員,學(xué)習(xí)一些函數(shù)式編程的思想和概念,對于手頭的開發(fā)工作和以后的職業(yè)發(fā)展,都是大有裨益的,下面這篇文章主要給大家介紹了關(guān)于Java8函數(shù)式編程的相關(guān)資料,需要的朋友可以參考下
    2022-01-01
  • 從源碼角度看spring mvc的請求處理過程

    從源碼角度看spring mvc的請求處理過程

    這篇文章主要介紹了從源碼角度看spring mvc的請求處理過程,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,,需要的朋友可以參考下
    2019-06-06
  • IDEA中多行注釋及取消注釋的快捷鍵分享

    IDEA中多行注釋及取消注釋的快捷鍵分享

    這篇文章主要介紹了IDEA中多行注釋及取消注釋的快捷鍵分享,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • Java基于直方圖應(yīng)用的相似圖片識別實例

    Java基于直方圖應(yīng)用的相似圖片識別實例

    這篇文章主要介紹了Java基于直方圖應(yīng)用的相似圖片識別實例,是非常實用的技巧,多見于圖形里游戲中,需要的朋友可以參考下
    2014-09-09
  • SpringBoot整合log4j2日志的實現(xiàn)

    SpringBoot整合log4j2日志的實現(xiàn)

    在項目推進中,如果說第一件事是搭Spring框架的話,那么第二件事情就是在Sring基礎(chǔ)上搭建日志框架,大家都知道日志對于一個項目的重要性,尤其是線上Web項目,因為日志可能是我們了解應(yīng)用如何執(zhí)行的唯一方式。此篇文章是博主在實踐中用Springboot整合log4j2日志的總結(jié)
    2021-06-06
  • 使用@Value為靜態(tài)變量導(dǎo)入并使用導(dǎo)入的靜態(tài)變量進行初始化方式

    使用@Value為靜態(tài)變量導(dǎo)入并使用導(dǎo)入的靜態(tài)變量進行初始化方式

    這篇文章主要介紹了使用@Value為靜態(tài)變量導(dǎo)入并使用導(dǎo)入的靜態(tài)變量進行初始化方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • Spring讀取配置文件屬性實現(xiàn)方法

    Spring讀取配置文件屬性實現(xiàn)方法

    這篇文章主要介紹了Spring讀取配置文件屬性實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-04-04
  • SpringBoot啟動失敗的解決方法:A component required a bean of type ‘xxxxxxx‘ that could not be found.

    SpringBoot啟動失敗的解決方法:A component required a&nb

    這篇文章主要介紹了解決SpringBoot啟動失?。篈 component required a bean of type ‘xxxxxxx‘ that could not be found.,目前解決方法有兩種,一種是不注入bean的方式,另一種是使用@Component的方式,本文給大家詳細講解,需要的朋友可以參考下
    2023-02-02
  • Java日常練習(xí)題,每天進步一點點(38)

    Java日常練習(xí)題,每天進步一點點(38)

    下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧,希望可以幫到你
    2021-07-07

最新評論

遂宁市| 遵义市| 汶川县| 景洪市| 肇源县| 福泉市| 独山县| 永州市| 噶尔县| 乌鲁木齐县| 沙河市| 青阳县| 老河口市| 巴南区| 丰镇市| 台东县| 台南市| 琼结县| 天水市| 江山市| 龙门县| 上饶县| 河北区| 建德市| 永德县| 临朐县| 麦盖提县| 金乡县| 葵青区| 五台县| 永州市| 陇川县| 抚松县| 双峰县| 镇坪县| 铁岭市| 三都| 苗栗市| 洮南市| 灵宝市| 旬阳县|