標籤:java hashcode equals set
Set中元素是無序的(存入和取出的順序不一定一致),元素不可以重複。
Set中的方法和Collection中的方法是一樣的。
常見子類:HashSet TreeSet
HashSet 底層資料結構是雜湊表
TreeSet 底層資料結構是二叉樹
import java.util.HashSet;import java.util.Iterator;class Person{private String name;private int age;public Person(String name, int age) {super();this.name = name;this.age = age;}//set and get methodspublic String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}public class SetDemo {public static void main(String[] args) {// TODO Auto-generated method stub//method1();method2();}public static void method1() {HashSet hs = new HashSet();hs.add("01");hs.add("02");hs.add("03");hs.add("04");// 無序性sop(hs);hs.add("02");// 唯一性sop(hs);sop("是否添加進去:" + hs.add("02"));}/** * 存入自訂對象,如果姓名和年齡相同視為同一個人,重複元素 */public static void method2 (){HashSet hs = new HashSet();hs.add(new Person("01",10));hs.add(new Person("02",11));hs.add(new Person("03",12));hs.add(new Person("04",13));/*列印Iterator it = hs.iterator();while (it.hasNext()){Person person = (Person)it.next();sop(person.getName()+"::"+person.getAge());}*///添加一個相同元素hs.add(new Person("01", 10));Iterator it = hs.iterator();while (it.hasNext()){Person person = (Person)it.next();sop(person.getName()+"::"+person.getAge());}//沒解決啊。。。兩個01::10}public static void sop(Object object) {System.out.println(object);}}
我們要求 姓名和年齡相同視為是重複元素,按照Set的特性來說是不應該被儲存的,結果卻是存上了。。。
解決:覆蓋元素的hashCode 方法,建立自己的雜湊值,同時覆蓋equals方法。
覆蓋元素HashCode方法 是因為,在Set中存入元素,首先被判斷的就是元素的雜湊值,只有當元素的雜湊值沒有出現過的時候,才會將元素存入。
覆蓋equals方法是因為,兩個元素的雜湊值相同,但是這兩個元素不一定是相同的,因此來判斷一下,並根據返回值來決定該元素最終能否被存入。
package ssssssss;import java.util.HashSet;import java.util.Iterator;class Person {private String name;private int age;public Person(String name, int age) {super();this.name = name;this.age = age;}public boolean equals(Object obj) {// TODO Auto-generated method stubif (!(obj instanceof Person))return false;Person person = (Person) obj;//列印 表示此方法被調用System.out.println(this.name + "******equals*****" + person.name);return this.name.equals(person.name) && this.age == person.age;}//覆蓋hashCode方法 建立Person自己的雜湊值public int hashCode() {// TODO Auto-generated method stubSystem.out.println(this.name + "..........hashCode");return 13;//按照條件設定雜湊值//return name.hashCode() + age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}public class SetDemo {public static void main(String[] args) {// TODO Auto-generated method stubmethod2();}/** * 存入自訂對象,如果姓名和年齡相同視為同一個人,重複元素 */public static void method2 (){HashSet hs = new HashSet();hs.add(new Person("01",10));hs.add(new Person("02",11));hs.add(new Person("03",12));hs.add(new Person("04",13));/*列印Iterator it = hs.iterator();while (it.hasNext()){Person person = (Person)it.next();sop(person.getName()+"::"+person.getAge());}*///添加一個相同元素hs.add(new Person("01", 10));Iterator it = hs.iterator();while (it.hasNext()){Person person = (Person)it.next();sop(person.getName()+"::"+person.getAge());}//沒解決啊。。。兩個01::10//覆蓋 hashcode方法,建立自己的雜湊值}public static void sop(Object object) {System.out.println(object);}}
列印結果:
01..........hashCode02..........hashCode02******equals*****0103..........hashCode03******equals*****0103******equals*****0204..........hashCode04******equals*****0104******equals*****0204******equals*****0301..........hashCode01******equals*****0101::1002::1103::1204::13
返回一個相同的雜湊值,通過列印結果我們不難猜出此程式的運行過程:
01先產生一個雜湊值,因為此時就只有01一個元素,所以存入
02再產生一個相同的雜湊值,然後跟01比較,不是同一元素,存入
03再產生相同的雜湊值,然後跟01和02進行比較,確定沒有相同元素,存入
04也是一樣,跟01 02 03比較完後,存入
接著就是重複元素01了,比較發現跟第一次存入的01是相同的,
返回false,沒有存入。
結論:
HashSet是如何保證元素唯一性的呢?
通過元素的兩個方法:hashCode和equals
只有當元素的雜湊值相等的時候才會判斷equals方法
那如果產生不同的雜湊值的話,就可以大大的減少程式的運行次數。
package ssssssss;import java.util.HashSet;import java.util.Iterator;class Person {private String name;private int age;public Person(String name, int age) {super();this.name = name;this.age = age;}public boolean equals(Object obj) {// TODO Auto-generated method stubif (!(obj instanceof Person))return false;Person person = (Person) obj;//列印 表示此方法被調用System.out.println(this.name + "******equals*****" + person.name);return this.name.equals(person.name) && this.age == person.age;}//覆蓋hashCode方法 建立Person自己的雜湊值public int hashCode() {// TODO Auto-generated method stubSystem.out.println(this.name + "..........hashCode");//return 13;//按照條件設定雜湊值return name.hashCode() + age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}public class SetDemo {public static void main(String[] args) {// TODO Auto-generated method stubmethod2();}/** * 存入自訂對象,如果姓名和年齡相同視為同一個人,重複元素 */public static void method2 (){HashSet hs = new HashSet();hs.add(new Person("01",10));hs.add(new Person("02",11));hs.add(new Person("03",12));hs.add(new Person("04",13));/*列印Iterator it = hs.iterator();while (it.hasNext()){Person person = (Person)it.next();sop(person.getName()+"::"+person.getAge());}*///添加一個相同元素hs.add(new Person("01", 10));Iterator it = hs.iterator();while (it.hasNext()){Person person = (Person)it.next();sop(person.getName()+"::"+person.getAge());}//沒解決啊。。。兩個01::10//覆蓋 hashcode方法,建立自己的雜湊值}public static void sop(Object object) {System.out.println(object);}}
Java---27---Set集合及其子類HashSet