hash值以及hashset 不能存重複值的原理
阿新 • • 發佈:2020-08-27
Object 裡面有個hashcode 方法
如以下程式碼:
package com.collectiondo;
class Person {
private Integer age;
private String name;
public Person(Integer age, String name) {
this.age = age;
this.name = name;
}
}
public class TestHash {
public static void main(String[] args) {
Person person1 = new Person(19,"路飛");
Person person2 = new Person(19,"路飛");
System.out.println("person1:"+person1.hashCode());//1173230247
System.out.println("person2:"+person2.hashCode());//1173230247
//String 重寫了hashcode的方法
String m=new String("路飛");
String n="路飛";
System.out.println( "m:"+m.hashCode());//1165519
System.out.println("n:"+n.hashCode());//1165519
//這兩個是特殊的
String str1 = "通話";
String str2 = "重地";
System.out.println("通話:"+"通話".hashCode());//雜湊值1179395
System.out.println("重地:"+"重地".hashCode());//雜湊值1179395
}
}
hashset 儲存資料的結構如下圖
hashset 不能存重複元素的原理,如下圖
用hashset 儲存自定義型別的資料(比如自己定義的物件,person ,student)
以下是示例:
package com.collectiondo; import java.util.HashSet; import java.util.Set; class Person { private Integer age; private String name; public Person(Integer age, String name) { this.age = age; this.name = name; } @Override public String toString() { return "Person{" + "age=" + age + ", name='" + name + '\'' + '}'; } } public class TestHash { public static void main(String[] args) { Set pset=new HashSet<Person>(); Person person1 = new Person(19,"路飛"); Person person2 = new Person(19,"路飛");
pset.add(person1); pset.add(person2);
System.out.println("person1:"+person1.hashCode());//1173230247 System.out.println("person2:"+person2.hashCode());//1173230247 System.out.println("pset:"+pset); }
輸出結果是:
person1:1173230247
person2:856419764
pset:[Person{age=19, name='路飛'}, Person{age=19, name='路飛'}]
從輸出的結果可以看出來,兩個person 雖然裡面的name 和age 屬性的值都是一樣的,但是由於hashcode 是不一樣的,所以被認為是不同的兩個例項。
顯然這樣是不合適的。所以我們要來改造一下person 類,在person 類裡面重寫hashcode 方法和equals方法
class Person { private Integer age; private String name; public Person(Integer age, String name) { this.age = age; this.name = name; } @Override public String toString() { return "Person{" + "age=" + age + ", name='" + name + '\'' + '}'; } //重寫equals方法 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return age.equals(person.age) && name.equals(person.name); } //重寫hashCode方法 @Override public int hashCode() { return Objects.hash(age, name); } }
測試程式碼:
public class TestHash { public static void main(String[] args) { Set pset=new HashSet<Person>(); Person person1 = new Person(19,"路飛"); Person person2 = new Person(19,"路飛"); Person person3= new Person(18,"娜美"); Person person4 = new Person(20,"索隆"); Person person5 = new Person(21,"山治"); pset.add(person1); pset.add(person2); pset.add(person3); pset.add(person4); pset.add(person5); System.out.println("person1:"+person1.hashCode());//1173230247 System.out.println("person2:"+person2.hashCode());//1173230247 System.out.println("pset:"+pset); } }
輸出的結果是:
person1:1167069
person2:1167069
pset:[Person{age=18, name='娜美'}, Person{age=19, name='路飛'}, Person{age=21, name='山治'}, Person{age=20, name='索隆'}]