Set 集合不容許包含相同的元素,若是試把兩個相同的元素加入同一個 Set 集合中,則添加操做失敗。html
Set 判斷兩個對象是否相同不是使用 == 運算符,而是根據 equals 方法。java
Set實現類:HashSet、LinkedHashSet、TreeSetshell
HashSet:經過散列表存信息,無序存儲,元素必須定義hashCode();數據結構
LinkedHashSet:內部使用鏈表維護元素順序,按順序插入順序排序,也必須定義hashCode();函數
TreeSet:經過樹結構(和TreeMap一致,使用紅黑樹)存儲元素,存儲數據有序。性能
HashSet :this
一、當向 HashSet 集合中存入一個元素時,HashSet 會調用該對象的 hashCode() 方法來獲得該對象的hashCode 值, 而後根據 hashCode 值決定該對象在 HashSet 中的存儲位置。spa
二、若是兩個元素的 equals() 方法返回 true,但它們的 hashCode() 返回值不相等,hashSet 將會把它們存儲在不一樣的位置,但依然能夠添加成功。code
三、HashSet 集合判斷兩個元素相等的標準:兩個對象經過 equals() 方法比較相等,而且兩個對象的hashCode() 方法返回值也相等。即:若是兩個對象經過 equals() 方法返回 true,這兩個對象的hashCode 值也應該相同。htm
重寫 hashCode() 方法的基本原則:
一、在程序運行時,同一個對象屢次調用 hashCode() 方法應該返回相同的值。
二、當兩個對象的 equals() 方法比較返回 true 時,這兩個對象的 hashCode() 方法的返回值也應相等。
三、對象中用做 equals() 方法比較的 Field,都應該用來計算 hashCode 值。
LinkedHashSet :
一、LinkedHashSet 是 HashSet 的子類。
二、LinkedHashSet 集合根據元素的 hashCode 值來決定元素的存儲位置,但它同時使用鏈表維護元素的次序,這使得元素看起來是以插入順序保存的。
三、LinkedHashSet 性能插入性能略低於 HashSet,但在迭代訪問 Set 裏的所有元素時有很好的性能。
四、LinkedHashSet 有序但不容許集合元素重複。
TreeSet:
TreeSet 是 SortedSet 接口的實現類,TreeSet 能夠確保集合元素處於排序狀態。
TreeSet 支持兩種排序方法:天然排序和定製排序。默認狀況下,TreeSet 採用天然排序。
排序:
一、TreeSet 會調用集合元素的 compareTo(Object obj) 方法來比較元素之間的大小關係,
而後將集合元素按升序排列。
二、若是試圖把一個對象添加到 TreeSet 時,則該對象的類必須實現 Comparable 接口。
三、實現 Comparable 的類必須實現 compareTo(Object obj) 方法,兩個對象即經過
compareTo(Object obj)方法的返回值來比較大小。
注意:
向 TreeSet 中添加的應該是同一個類的對象,
當須要把一個對象放入 TreeSet 中,重寫該對象對應的 equals() 方法時,應保證該方法與
compareTo(Object obj) 方法有一致的結果:即若是兩個對象經過 equals() 方法比較返回 true,
則經過 compareTo(Object obj) 方法比較應返回 0。
天然排序:
import java.util.*; /* TreeSet:能夠對Set集合中的元素進行排序。 底層數據結構是二叉樹。 保證元素惟一性的依據: compareTo方法return 0. TreeSet排序的第一種方式:讓元素自身具有比較性。 元素須要實現Comparable接口,覆蓋compareTo方法。 也種方式也成爲元素的天然順序,或者叫作默認順序。 TreeSet的第二種排序方式。 當元素自身不具有比較性時,或者具有的比較性不是所須要的。 這時就須要讓集合自身具有比較性。 在集合初始化時,就有了比較方式。 需求: 往TreeSet集合中存儲自定義對象學生。 想按照學生的年齡進行排序。 記住,排序時,當主要條件相同時,必定判斷一下次要條件。 */ class Treeset { public static void main(String[] args) { Set ts = new TreeSet(); ts.add(new Student("lisi02", 22)); ts.add(new Student("lisi007", 20)); ts.add(new Student("lisi09", 19)); ts.add(new Student("lisi08", 19)); // ts.add(new Student("lisi007",20)); // ts.add(new Student("lisi01",40)); Iterator it = ts.iterator(); while (it.hasNext()) { Student stu = (Student) it.next(); System.out.println(stu.getName() + "..." + stu.getAge()); } } } class Student implements Comparable// 該接口強制讓學生具有比較性。 { private String name; private int age; Student(String name, int age) { this.name = name; this.age = age; } public int compareTo(Object obj) { // return 0; if (!(obj instanceof Student)) throw new RuntimeException("不是學生對象"); Student s = (Student) obj; System.out.println(this.name + "....compareto....." + s.name); if (this.age > s.age) return 1; if (this.age == s.age) { return this.name.compareTo(s.name); } return -1; } public String getName() { return name; } public int getAge() { return age; } }
定製排序:
import java.util.*; /* 當元素自身不具有比較性,或者具有的比較性不是所須要的。 這時須要讓容器自身具有比較性。 定義了比較器,將比較器對象做爲參數傳遞給TreeSet集合的構造函數。 當兩種排序都存在時,以比較器爲主。 定義一個類,實現Comparator接口,覆蓋compare方法。 */ class Student implements Comparable//該接口強制讓學生具有比較性。 { private String name; private int age; Student(String name,int age) { this.name = name; this.age = age; } public int compareTo(Object obj) { //return 0; if(!(obj instanceof Student)) throw new RuntimeException("不是學生對象"); Student s = (Student)obj; //System.out.println(this.name+"....compareto....."+s.name); if(this.age>s.age) return 1; if(this.age==s.age) { return this.name.compareTo(s.name); } return -1; } public String getName() { return name; } public int getAge() { return age; } } class TreeSetDemo2 { public static void main(String[] args) { Set ts = new TreeSet(); ts.add(new Student("lisi02",22)); ts.add(new Student("lisi02",21)); ts.add(new Student("lisi007",20)); ts.add(new Student("lisi09",19)); ts.add(new Student("lisi06",18)); ts.add(new Student("lisi06",18)); ts.add(new Student("lisi007",29)); //ts.add(new Student("lisi007",20)); //ts.add(new Student("lisi01",40)); Iterator it = ts.iterator(); while(it.hasNext()) { Student stu = (Student)it.next(); System.out.println(stu.getName()+"..."+stu.getAge()); } } } class MyCompare implements Comparator { public int compare(Object o1,Object o2) { Student s1 = (Student)o1; Student s2 = (Student)o2; int num = s1.getName().compareTo(s2.getName()); if(num==0) { return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge())); /* if(s1.getAge()>s2.getAge()) return 1; if(s1.getAge()==s2.getAge()) return 0; return -1; */ } return num; } }
性能分析:能夠參考《Thinking in java》,數據以下:
------------- TreeSet -------------
size add contains iterate
10 1316 506 180
100 199 101 22
1000 250 174 19
10000 266 224 21
------------- HashSet -------------
size add contains iterate
10 1717 325 242
100 59 16 43
1000 66 25 27
10000 66 28 25
---------- LinkedHashSet ----------
size add contains iterate
10 516 151 72
100 127 40 29
1000 145 57 27
10000 125 53 25
能夠看出HashSet性能基本總比TreeSet好 ,除非肯定須要排序時,才該使用TreeSet。
該博客僅做爲複習記錄。
本文大多數參考:http://www.cnblogs.com/shellway/p/3709074.html