==和equals的区别
==的含义
1、基础数据类型:比较的是他们的值是否相等,比如两个int类型的变量,比较的是变量的值是否一样。 2、引用数据类型:比较的是引用的地址是否相同,比如两个User对象,比较的就是指向的引用地址是否相同
equals的含义
先来看一下java.lang.Object类的实现
public boolean equals(Object obj) {
return (this == obj);
}
因为所有的类都是默认继承自java.lang.Object,如果子类没有重写equals方法的话,那这个equals就跟==是一样的,引用类型就是比较的应用地址,基本数据类型就是比较的值。
重写equals方法
首先equals作为一个方法,我们可以通过重新这个方法。 比如
public class User {
private long idCard;
private String name;
public static void main(String[] args) {
User user1 = new User(123456, "张三");
User user2 = new User(123456, "张三");
System.out.println(user1.equals(user2)); ##输出false
}
public User(long idCard, String name) {
this.idCard = idCard;
this.name = name;
}
}
看到我们new了两个User对象,他们的两个属性都相同,但是他们指向不同的引用地址,equals方法返回false
下面我们重写equals方法,我们认为只要User对象的两个属性都相同这个两个User对象就相同。
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (obj instanceof User) {
User tmpUser = (User) obj;
return (this.idCard == tmpUser.idCard && this.getName().equals(((User) obj).getName())) ? true : false;
}
return false;
}
同样运行上面的main方法,输出true;
可能有些童鞋注意到上面重写的equals方法里用到了字符串的equals方法。 String的equals方法有没有重写Object的equals方法呢,如果重写了又是怎么实现的? 下面是java.lang.String的equals方法的实现
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
我们看到,字符串的equals方法实际上是比较的每个字节是否相同,全部相同才会返回true。关于String更多的问题参考String的介绍
几个典型的重写equals方法的类
java.util.AbstractMap 我们使用的比较多的HashMap就是继承自该类。它是实现了一个深度比较,遍历每个键值对,比较每个键值对。
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof Map))
return false;
Map<?,?> m = (Map<?,?>) o;
if (m.size() != size())
return false;
try {
Iterator<Entry<K,V>> i = entrySet().iterator();
while (i.hasNext()) {
Entry<K,V> e = i.next();
K key = e.getKey();
V value = e.getValue();
if (value == null) {
if (!(m.get(key)==null && m.containsKey(key)))
return false;
} else {
if (!value.equals(m.get(key)))
return false;
}
}
} catch (ClassCastException unused) {
return false;
} catch (NullPointerException unused) {
return false;
}
return true;
}
同样的还有java.util.AbstractList 它是ArrayList的父类,也是循环遍历每个元素是否相等,只有所有元素相同才会返回true。
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof List))
return false;
ListIterator<E> e1 = listIterator();
ListIterator<?> e2 = ((List<?>) o).listIterator();
while (e1.hasNext() && e2.hasNext()) {
E o1 = e1.next();
Object o2 = e2.next();
if (!(o1==null ? o2==null : o1.equals(o2)))
return false;
}
return !(e1.hasNext() || e2.hasNext());
}
重写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。
--------------------------end-------------------------
对你有帮助的话,记得点个赞👍
- [六十七点五 ]
--------------------------end-------------------------