==和equals()的区别
== 的使用
==:运算符
- == 符号可以使用在基本数据类型变量和引用数据类型变量中。
- ① 如果比较的是基本数据类型变量,比较两个变量保存的数据是否相等。(不一定类型要相同,因为有自动类型提升)
②如果比较的是引用数据类型变量,比较两个对象的地址是否相同,即两个引用是否指向同一个对象实体。
③ == 符号使用时,必须保证符号左右两边的变量类型一致。
equals() 的使用
(1)equals() 是一个方法,而非运算符。
(2)equals() 只能适用于引用数据类型。
(3)Object中equals()的定义:
public boolean equals(Object obj) {
return (this == obj);
}
说明:Object类中定义的equals()和==的作用是相同的,比较两个对象的地址是否相同,即两个引用是否指向同一个对象实体。
(4)像String、Date、File、包装类等都重写了Object类中的equals()方法。 重写以后,比较的不是两个引用的地址是否相同,而是比较两个对象的“实体内容 ”是否相同。这里的“实体内容 ”指给属性赋的值。
(5)通常情况下,我们自定义类如果使用equals()方法的话,也通常比较两个对象的实体内容相同。
那么,我们就需要对Object类中的equals()进行重写。
equals()重写原则:比较两个对象的实体内容(即所有属性)是否相同。
手动实现equals()重写
以类Custoer为例,此类为自定类,该类包括两个属性name:String,age:int,比较由Customer创建的两个对象,就分别比较两个对象的实体内容(即name,age)是否相等。手动实现equals()重写如下:
// equals()重写原则:比较两个对象的实体内容(即,name和age)是否相同。
@Override
public boolean equals(Object obj) {
if (this == obj) {// 当前对象和形参的引用地址一样,返回true。
return true;
}
if (obj instanceof Customer) {// 看一下形参是否是Customer类型,利用关键字instanceof
Customer cust = (Customer) obj;
// 比较两个对象的每个属性是否都相同。
//方法一:
// if(this.age == cust.age &&
// this.name.equals(cust.name)){//name为String类型,使用.equals()比较的是内容。
// return true;
// }else{
// return false;
// }
// 方法二:
return this.age == cust.age && this.name.equals(cust.name);
}
return false;
}
快捷键实现equals()重写
利用快捷键 alt+shift+s 调用equals(),具体比较哪个属性来判断对象内容是否相等就要根据实际开发需求判定。代码如下:
//自动生成的equals()
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Customer other = (Customer) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
equals()重写举例
例子1
编写Order类,有int型的orderId,String型的orderName,相应的getter()和setter()方法,两个参数的构造器,重写父类的equals()方法:public boolean equals(Object obj),并判断测试类中创建的两个对象是否相等。
创建Order类
public class Order {
private int orderId;
private String orderName;
//带参构造器
public Order(int orderId, String orderName) {
super();//调用父类Object空参构造器
this.orderId = orderId;
this.orderName = orderName;
}
//手动重写equals()
@Override
public boolean equals(Object obj) {
if(this == obj){
return true;
}
if(obj instanceof Order){
Order order = (Order)obj;//强制转换,向下转型,实现调用真实对象的属性和方法。
//正确的写法
return this.orderId == order.orderId && this.orderName.equals(order.orderName);
//错误的写法
// return this.orderId == order.orderId && this.orderName == order.orderName;
}else{
return false;
}
}
//get和set
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;
}
}
创建OrderTest类
public class OrderTest {
public static void main(String[] args) {
Order order1 = new Order(1001, "jack");
Order order2 = new Order(1001, "jack");
System.out.println("order1与order2是否相等:" + order1.equals(order2));
Order order3 = new Order(1002, "jack");
System.out.println("order1与order3是否相等:" + order1.equals(order3));
String s1 = "BB";
String s2 = "BB";
System.out.println("s1与s2是否相等:" + s1.equals(s2));
System.out.println("s1与s2是否相等:" + (s1 == s2));//true
}
}
例子2
请根据以下代码自行定义能满足需要的MyDate类,在MyDate类中覆盖equals方法,使其判断当两个MyDate类型对象的年月日都相同时,结果为true,否则为false。
创建MyDateTest类
public class MyDateTest {
public static void main(String[] args) {
MyDate m1 = new MyDate(14, 3, 1976);
MyDate m2 = new MyDate(14, 3, 1976);
if (m1 == m2) {
System.out.println("m1==m2");
} else {
System.out.println("m1!=m2"); // m1 != m2
}
if (m1.equals(m2)) {
System.out.println("m1 is equal to m2");// 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;
}
//手写重写equals()
@Override
public boolean equals(Object obj) {
if(this == obj){
return true;
}
if(obj instanceof MyDate){
MyDate date = (MyDate)obj;
return this.day == date.day
&& this.month == date.month
&& this.year == date.year;
}
return false;
}
//开发中使用快捷键alt+shift+s调用equals();初学还是手写一下比较好,可以加深对程序的理解
// @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;
// }
//get和set方法
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;
}
}
例子3
定义两个类,父类GeometricObject代表几何形状,子类Circle代表圆形。(细节不在赘述,直接code)写一个测试类,创建两Circle对象,判断其颜色是否相等;利用equals方法判断其半径是否相等;利用toString()方法输出其半径。
创建GeometricObject类
public class GeometricObject {
protected String color;
protected double weight;
//构造器空参
public GeometricObject() {
super();
color = "white";
weight = 1.0;
}
//构造器含参
public GeometricObject(String color, double weight) {
super();
this.color = color;
this.weight = weight;
}
//
//get和set
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
}
创建Circle类
public class Circle extends GeometricObject {
private double radius;
//构造器
public Circle() {
super();
// color = "white";
// weight = 1.0;
radius = 1.0;
}
public Circle(double radius) {
super();
// color = "white";
// weight = 1.0;
this.radius = radius;
}
public Circle(double radius,String color,double weight) {
super(color, weight);
this.radius = radius;
}
//get和set方法
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
//计算圆的面积
public double findArea(){
return Math.PI * radius * radius;
}
//重写equals()
@Override
public boolean equals(Object obj) {
if(this == obj){
return true;
}
if(obj instanceof Circle){
Circle circle = (Circle)obj;
return this.radius == circle.radius;
}
return false;
}
//重写toString()
@Override
public String toString() {
return "Circle [radius=" + radius + "]";
}
}
创建CircleTest类
public class CircleTest {
public static void main(String[] args) {
Circle circle1 = new Circle(3, "white", 1.0);
Circle circle2 = new Circle(3, "white", 1.0);
System.out.println("circle1和circle2颜色是否相等:" + circle1.getColor().equals(circle2.getColor()));
System.out.println("circle1和circle2半径是否相等:" + circle1.equals(circle2));
System.out.println(circle1.toString());
System.out.println(circle2.toString());
}
}
说明:上面的toString()实现了重写,由于比较简单,这里直接使用快捷键进行调用。
综上,通过上述内容,我们可以很好地理解==和equals()的区别。
参考
https://www.bilibili.com/video/BV1Kb411W75N?p=302&vd_source=e3d2dcdad07ba1c727f3c9e7654f60b5