hashCode
public static void main(String[] args) {
Person person = new Person();
int p = person.hashCode();
System.out.println(p);//实际上是调用Object的toString方法
System.out.println(person);
}
我们所说的地址值,实际上是哈希值的16进制
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
String
String s = new String("abc");
String s1 = new String("abc");
System.out.println(s == s1);
System.out.println(s.hashCode() == s1.hashCode());
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210622090624876.png
String重写了hashCode方法
String.class
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
思考:
只要字符串内容一样,哈希值必定一样。
如果两个字符串的哈希值一样,那么内容可能不一样。(“abc"和"acD”、“通话"和"重地”)
HashSet(哈希表结构,数组+链表,无序)
1、先判断新旧元素的哈希值
2、再判断新旧元素的equals,也相同则判断重复
public static void main(String[] args) {
HashSet<String> hashSet = new HashSet<>();
hashSet.add("qwq");
hashSet.add("java");
hashSet.add("abc");
hashSet.add("asd");
hashSet.add("acD");
hashSet.add("qwe");
System.out.println(hashSet);
}
LinkedHashSet(哈希表结构,数组+链表,有序)
存储时的原理同上
public static void main(String[] args) {
HashSet<String> hashSet = new LinkedHashSet<>();
hashSet.add("qwq");
hashSet.add("java");
hashSet.add("abc");
hashSet.add("asd");
hashSet.add("acD");
hashSet.add("qwe");
System.out.println(hashSet);
}
保证自定义元素的一致性(重写hashCode和equals)
public static void main(String[] args) {
HashSet<Dog> dogs = new HashSet<>();
dogs.add(new Dog(18, "旺财"));
dogs.add(new Dog(19, "小旺财"));
dogs.add(new Dog(20, "中旺财"));
dogs.add(new Dog(30, "老旺财"));
dogs.add(new Dog(30, "老旺财"));
System.out.println(dogs);
}
重写hashCode和equals之前
重写之后
Dog.class
//重写hashCode
@Override
public int hashCode() {
return age*17 + name.hashCode()*99;
}
//重写equals
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Dog dog = (Dog) o;
return age == dog.age &&
name.equals(dog.name);
}
总结:用哈希表结构存对象时,要保证元素的唯一性则需要重写hashCode和equals方法
定义一个标准的类:
1、封装(private+get/set)
2、构造(无参+有参)
3、toString(快速打印对象信息)
4、hashCode和equals(保证元素使用哈希表结构存储时的唯一性)
contains方法,判断是否包含某一个元素
ArrayList的contains方法:(性能低)
names.contains(“abc”);//将names集合中每一个元素进行遍历,只比较equals的返回值,为true则包含。
HashSet的contains方法:原理和add方法
set.contains(“abc”);//先判断哈希值,再判断equals,都为true则包含。