class Person{
int a;
Person(int a){
this.a = a;
}
}
public class Test {
public static void main(String[] args) {
int a = 1;
int b = 1;
System.out.println(a == b);// 比较值
System.out.println("--------");
Person ap = new Person(1);
Person bp = new Person(2);
System.out.println(ap == bp); // 比较地址
System.out.println(ap.equals(bp)); // 调用obj的equals()
System.out.println("--------");
bp = ap;
System.out.println(ap == bp);
System.out.println(ap.equals(bp));
System.out.println("--------");
String as = "123";
String bs = "123";
System.out.println(as == bs);
System.out.println(as.equals(bs));
System.out.println("--------");
bs = new String("123");
System.out.println(as == bs);
System.out.println(as.equals(bs));
}
}
输出结果:
true
--------
false
false
--------
true
true
--------
true
true
--------
false
true
调用这个方法
class Person{
int a;
Person(int a){
this.a = a;
}
public boolean equals(Person b){
if(a == b.a){
return true;
}
return false;
}
}
public class Test {
public static void main(String[] args) {
Person ap = new Person(1);
Person bp = new Person(1);
System.out.println(ap.equals(bp));
}
}
运行结果:
true
object类的equals()
public boolean equals(Object obj) {
return (this == obj);
}
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;
}
HashSet是基于HashMap来实现的,实现了Set接口,同时还实现了序列化和可克隆化。
其中最有趣的是hashcode()方法
添加元素:
import java.util.HashSet;
public class Test {
public static void main(String[] args) {
HashSet<Integer> hash = new HashSet<>();
hash.add(1);
hash.add(2);
System.out.println(hash); // [1,2]
}
}
add()方法底层
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
put()的底层
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
hash()底层
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
hashCode就是对象的散列码,是根据对象的某些信息推导出的一个整数值,默认情况下表示是对象的存储地址。通过散列码,可以提高检索的效率,主要用于在散列存储结构中快速确定对象的存储地址,如Hashtable、hashMap中。
Java的超类Object类已经定义了equals()和hashCode()方法,在Obeject类中,equals()比较的是两个对象的内存地址是否相等,而hashCode()返回的是对象的内存地址。所以hashCode主要是用于查找使用的,而equals()是用于比较两个对象是否相等的。但有时候我们根据特定的需求,可能要重写这两个方法,在重写这两个方法的时候,主要注意保持一下几个特性:
(1)如果两个对象的equals()结果为true,那么这两个对象的hashCode一定相同;
(2)两个对象的hashCode()结果相同,并不能代表两个对象的equals()一定为true,只能够说明这两个对象在一个散列存储结构中。
(3)如果对象的equals()被重写,那么对象的hashCode()也要重写。
假设我们我们重写了对象的equals(),但是不重写hashCode()方法,由于超类Object中的hashcode()方法始终返回的是一个对象的内存地址,而不同对象的这个内存地址永远是不相等的。这时候,即使我们重写了equals()方法,也不会有特定的效果的,因为不能确保两个equals()结果为true的两个对象会被散列在同一个存储区域,即 obj1.equals(obj2) 的结果为true,但是不能保证 obj1.hashCode() == obj2.hashCode() 表达式的结果也为true;这种情况,就会导致数据出现不唯一,因为如果连hashCode()都不相等的话,就不会调用equals方法进行比较了,所以重写equals()就没有意义了。
Java中哈希集(HashSet)概念,实现以及操作
集合框架:Set集合的特点、HashSet集合的底层原理、哈希表、实现去重复
必须掌握的hashcode()方法