1. 程式人生 > >Set常用子類特點

Set常用子類特點

哈希 rabl -h style 解決 back 對象 shm name

HashSet: 重寫 hashCode和equals方法
特點:無序,唯一
底層結構是:
哈希表:元素為鏈表的數組。綜合了鏈表和數組的好處
add方法:底層實際是依賴於HashCode()和equals()方法

HashSet實際用的是HashMap
public HashSet() {
map = new HashMap<>();
}

案例-HashSet存儲自定義對象


出現問題:
重復的元素也被添加了,不能保證元素唯一性

原因:自定義類沒有重寫HashCode和equals方法;

分析:
(1) 默認繼承Object類的HashCode和equals方法,而Object的HashCode值是通過對象


的內部地址值轉換為一個整數得到的,不同的對象的地址值不同,進而可以知道轉換後
的HashCode值也不可能相同。HashCode值不同就當作不是重復的元素而添加了。
(2)equals方法默認也是比較地址值,如果不重寫equals方法,那麽不同的對象
比較的結果也一定就是false;將會當作不是重復元素而添加了

解決:重寫自定義類的HashCode和equals方法

思考:重寫HashCode(),那麽HashCode值跟什麽有關系呢?
答: 和對象的成員變量值有關系

重寫HashCode方法:
就將對象的成員變量值相加:
基本類型:直接相加
引用類型:就加哈希值

// return name.hashCode()+age;
// 代碼優化如下
return name.hashCode()+age*31;

註意:判斷是否是重復元素步驟:
1-先比較HashCode值:
1-1:如果HashCode值不同:直接添加
1-2:如果HashCode值相同:
1-2-1:繼續判斷equals方法:
返回false:添加元素
返回true:放棄添加

對於hashCode和equals方法的理解:(新華字典: 即使是在同一頁了,也有可能不是同一個元素)
同一頁:hashCode值
同一頁中同一個元素:hashCode值相同情況下,還要繼續采用equals方法判斷

二、LinkedHashSet:
底層數據結構是:鏈表和哈希表
鏈表保證元素有序
哈希表保證元素唯一

三、TreeSet:

(1)實現Comparable自然排序接口,重寫compareTo方法

(2)實現Comparator比較器排序接口,重寫compare方法

排序方式:以構造函數確定排序方式
A 無參構造:自然排序
class Student implements Comparable<Student>{
@Override
public int compareTo(Student s){
//按年齡排序
int num=this.age-s.age;
//隱含條件,年齡相同時,應該繼續比較姓名
int num2=num==0?this.name.compareTo(s.name):num;
return num2;
}
}

B 有參構造:比較器排序 將自定義的比較器類對象作為構造方法的參數
class MyComparator implements Comparator<Student>{
@Override
public int compare(Student s1,Student s2){
int num=(int)(stu2.getTotal()-stu1.getTotal());
int num2=num==0?stu1.getName().compareTo(stu2.getName()):num;
return num2;
}
}
TreeSet<Student> ts=new TreeSet<Student>(new MyComparator());

---------------------------------------------
字符串的比較
int compareTo(String str):

Set常用子類特點