一、“==”的使用
"=="运算符可以使用在基本类型变量和引用类型变量中
- 如果比较的是基本数据类型变量,比较的是两个变量保存的数据是否相等,(不一定要求数据类型严格相同),只要两个变量的值相等,就将返回true。
- 如果比较的是引用类型变量,它们必须指向同一个对象时,==判断才返回true。==不可用于比较类型上没有父子关系的两个对象。
public class Equals {
public static void main(String[] args) {
//基本数据类型
int i=10;
int j=10;
double d=10.0;
System.out.println(i==j);//true
System.out.println(i==d);//true
boolean b=true;
//编译都报错
// System.out.println(i==b);
char c=10;
System.out.println(i==c);//true
char c1='A';
char c2=65;
System.out.println(c1==c2);//true
//引用类型 Customer是自定义的类
Customer cust1=new Customer("Tom", 21);
Customer cust2=new Customer("Tom", 21);
System.out.println(cust1==cust2);//false
String s1=new String("hello");
String s2=new String("hello");
System.out.println(s1==s2); //false
System.out.println(s1.equals(s2));//true
}
运行上面程序可以看到整形10、浮点型10.0以及char类型的10都是相等的。但cust1和cust2两个变量都是引用类型变量,它们分别指向两个通过new关键字创建的String对象,因此str1和str2两个变量不相等。但是我们在很多时候,程序判断两个引用变量是否相等时,也希望有一种类似于“值相等”的判断规则,并不严格要求两个引用变量指向同一个对象。例如对于两个字符串变量,可能只是要求它们引用字符串对象里包含的字符序列相同即可认为相等。此时就可以利用String对象的equals方法来进行判断,例如上面的程序中s1.equals(s2)将返回true。
二、 “equals()”的使用
- 是Object类中的一个方法,而非运算符,所以只要声明了一个类就可以调用equals()。
- 只能适用于引用数据类型。
- Object类中equals()的定义:
可以看出Object类中定义的equals()和==的作用是相同的:比较两个对象的地址值是否相同,即两个引用是否指向同一个对象实体。
- 像String、Date、File、包装类等都重写了Object类中的equals()方法。重写以后,比较的不是两个引用的地址是否相同,而是比较两个对象的"实体内容"(一般就是属性值)是否相同。
- 通常情况下,我们自定义的类如果使用equals()的话,也通常是比较两个对象的"实体内容"是否相同。那么,我们就需要对Object类中的equals()进行重写。重写的原则:比较两个对象的实体内容是否相同.
- 开发中都是自动生成的,不会自己手写,但是还要会手写的流程的
自己重写equals方法举例
class User{
String name;
int age;
//重写其equals()方法
public boolean equals(Object obj){
if(obj == this){
return true;
}
if(obj instanceof User){
User u = (User)obj;
return this.age == u.age && this.name.equals(u.name);
}
return false;
}
通常我们都是自动生成的equals方法,eclipse中在代码编辑区右键–>source–>Generate hashCode() and equals()点击ok,会多一个hashCode方法,可以先把它删掉,只留下一个equals()
练习
1、
package com.liuyongbin.equalsExer;
/*
* 编写Order类,有int型的orderId,String型的orderName,
* 相应的getter()和setter()方法,两个参数的构造器,
* 重写父类的equals()方法:public boolean equals(Object obj),
* 并判断测试类中创建的两个对象是否相等。
*/
public class OrderTest {
public static void main(String[] args) {
Order order1=new Order(1001, "刘瘦瘦");
Order order2=new Order(1001, "刘瘦瘦");
System.out.println(order1==order2);//false
System.out.println(order1.equals(order2));//true
/*如果使用下面的equals方法即
* return this.orderId==order.orderId &&
this.orderName.equals(order.orderName);
上面的结果不变?为什么我比较orderName时使用的"=="(比较地址)时候还是true
回答:因为我们使用这种声明方式:String s1="刘瘦瘦";String s2="刘瘦瘦";时,会把
"刘瘦瘦"放在常量池中,在声明s2时,发现常量池中已经存在,直接把"刘瘦瘦"的首地址赋给s2
这也就表名地址相同了
**/
Order order3=new Order(1001, new String("刘瘦瘦"));
Order order4=new Order(1001, "刘瘦瘦");
System.out.println(order3==order4);//false
System.out.println(order3.equals(order4));//false
Order order5=new Order(1001, new String("刘瘦瘦"));
Order order6=new Order(1001, new String("刘瘦瘦"));
System.out.println(order5==order6);//false
System.out.println(order5.equals(order6));//false
}
}
class Order{
private int orderId;
private String orderName;
public Order(int orderId, String orderName) {
super();
this.orderId = orderId;
this.orderName = orderName;
}
public int getOrderId() {
return orderId;
}
public void setOrderId(int orderId) {
this.orderId = orderId;
}
public String getOrderName() {
return orderName;
}
public void setOrderName(String orderName) {
this.orderName = orderName;
}
@Override
public boolean equals(Object obj) {
if(this==obj){
return true;
}
if(obj instanceof Order){
Order order=(Order)obj;//为啥要强制?因为此时相当于Object obj=new Order();
//发生了多态,如果我们不强转(向下转型),就无法调用Order里的特有属性和方法
//正确的
// return this.orderId==order.orderId &&
// this.orderName.equals(order.orderName);
//错误的:
return this.orderId==order.orderId &&
this.orderName==(order.orderName);
}
return false;
}
}
2、
public class MyDataTest {
public static void main(String[] args) {
MyDate m1=new MyDate(14,2,1976);
MyDate m2=new MyDate(14, 2, 1976);
if(m1==m2){
System.out.println("m1=m2");
}else{//输出
System.out.println("m1!=m2");
}
if(m1.equals(m2)){//输出
System.out.println("m1 is equal to m2");
}else{
System.out.println("m1 is not equal to m2");
}
}
}
class MyDate{
private int day;
private int month;
private int year;
public MyDate(int day, int month, int year) {
super();
this.day = day;
this.month = month;
this.year = year;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
//自动生成的
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
MyDate other = (MyDate) obj;
if (day != other.day)
return false;
if (month != other.month)
return false;
if (year != other.year)
return false;
return true;
}
// 自己手写的
// public boolean equals(Object obj){
// if(this==obj){
// return true;
// }
//
// if(obj instanceof MyDate){
// MyDate myDate=(MyDate)obj;
// return this.day==myDate.day && this.month==myDate.month &&
// this.year==myDate.year;
//
// }
// return false;
// }
}