Set集合以及HashSet、LinkedHashSet、TreeSet等讲解
生活随笔
收集整理的這篇文章主要介紹了
Set集合以及HashSet、LinkedHashSet、TreeSet等讲解
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?Set
?Set 集合不允許包含相同的元素,如果試把兩個相同的元素加入同一個 Set 集合中,則添加操作失敗。
?Set 判斷兩個對象是否相同不是使用== 運算符,而是根據 equals 方法
?HashSet 是 Set 接口的典型實現,大多數時候使用Set 集合時都使用這個實現類。 ?HashSet 按 Hash 算法來存儲集合中的元素,因此具有很好的存取和查找性能。 ?HashSet 具有以下特點: –不能保證元素的排列順序 –HashSet不是線程安全的 –集合元素可以使 null ?當向 HashSet 集合中存入一個元素時,HashSet 會調用該對象的 hashCode() 方法來得到該對象的hashCode 值,然后根據 hashCode 值決定該對象在 HashSet 中的存儲位置。 ?如果兩個元素的 equals() 方法返回 true,但它們的 hashCode() 返回值不相等,hashSet 將會把它們存儲在不同的位置,但依然可以添加成功。
?LinkedHashSet 是 HashSet 的子類 ?LinkedHashSet 集合根據元素的 hashCode 值來決定元素的存儲位置,但它同時使用鏈表維護元素的次序,這使得元素看起來是以插入順序保存的。 ?LinkedHashSet性能插入性能略低于 HashSet,但在迭代訪問 Set 里的全部元素時有很好的性能。 ?LinkedHashSet不允許集合元素重復。
?TreeSet 是 SortedSet 接口的實現類,TreeSet可以確保集合元素處于排序狀態。 ?TreeSet支持兩種排序方法:自然排序和定制排序。默認情況下,TreeSet采用自然排序。
package com.hbut.test;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import com.hbut.domain.Person;
/**
?* Set(接口):放置的元素是按照哈希表來放的,元素是無序的;
?* ? ?注意:1.放置元素時使用對象的equals方法判斷的;
?* ? ? ? ? ? ? ? 2.可以放置null(null其實既不是類,也不是類型 )值,但是只能放一個;
?* ? ?HashSet是Set接口的實現類,是非線程安全的,一般用的比較多,非線程安全可以轉為線程安全的;
?* ? ? ? ?LinkedHashSet:是HashSet的子類,對插入的數據是有序的,他的底層不僅有hash算法,還有鏈表維護,里面也不能有重復的元素。
?* ? ? ? ??
?* ? ?
?*
?*/
public class TestSet {
public static void main(String[] args) {
Set set = new LinkedHashSet();//保證set的有序
set.add(null);
set.add(null);
System.out.println(set.size());
Person person =new Person();
Person person2 =new Person();
System.out.println(person.hashCode()); ? ?//注意:沒有復寫person的hashcode方法的話,那么兩個對象是存在不一樣的地方的。
System.out.println(person2.hashCode());
System.out.println(person.equals(person2));//注意:已經復寫了person的equals方法了
System.out.println(person==person2);
set.add(person);//添加的是同一對象
set.add(person2);
System.out.println(set.size());
set.add(new Person("xx",21)); ?//并未覆寫equals方法,所以是兩個不同的對象,無法比較。如果復寫了,那么就是一個了,去試試
set.add(new Person("xx",21)); ??
System.out.println(set.size());
set.add("hello");
Iterator it = set.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
//對于TreeSet的實驗 package com.hbut.test;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
import com.hbut.domain.Student;
import com.hbut.exeception.StudentExeception;
import com.hbut.util.MyComparator;
public class TestTreeSet {
/**
* 1.如果使用treeSet的無參數構造器來創建對象,那么添加的對象必須實現Comparable接口,復寫compareTo方法,不能放入null,不然會發生空指針異常;
* 2.不能傳不是同一類對象,不然會發生類型轉換異常ClassCastExeception異常
* 3.兩個對象是按照Comparable的接口的comparaTo方法比較,是由TreeSet調用此方法
*?
* (1).要么類實現Comparable接口,復寫ComparaTo方法;
* (2).要么寫一個比較器,Comparator 復寫compare方法;(推薦這種,比較方法,可以直接使用)
*/
public static void main(String[] args) {
// Set st= new TreeSet();
//
// //st.add(null);
//
// st.add("BB"); ?//對放入的元素默認是按照自然順序排序的,元素也是不可重復的,注意:還可以定制的;
// st.add("AA");
// st.add("CC");
//
// st.add("2");
// st.add("1");
// st.add("3");
//
int x=22;
st.add(x);
//
//
// for(Object obj :st){
//
// System.out.println(obj);
//
// }
Set st2= new TreeSet<>();
st2.add(new Student("BB",95));
st2.add(new Student("AA",95));//注意:此時的comparaTo返回的是true,是一樣的分數,放不進去,與equals方法相背,需要注意,一般要求兩個最好返回一樣的值
st2.add(new Student("DD",91));
st2.add(new Student("CC",94));
for(Object obj :st2){
System.out.println(obj);
? ? }
Comparator ct = new MyComparator();
Comparator comparator = new Comparator() {//匿名內部類,這是一個比較器
@Override
public int compare(Object o1, Object o2){
if(o1 instanceof Student && o2 instanceof Student){
Student s1= (Student) o1;
Student s2= (Student) o2;
return s1.getScore()-s2.getScore();
}
else{
throw new ClassCastException("不是Student");
}
}
};
Set s3= new TreeSet<>(ct);
s3.add(new Student("yy",66));
s3.add(new Student("xx",65));
s3.add(new Student("zz",70));
System.out.println("--------用傳入Comparator方法可行------------");
for(Object obj : s3){
System.out.println(obj);
? ? }
try {
test();//需要對異常進行處理。不然直接拋給虛擬機了
} catch (StudentExeception e) {
//System.out.println(e.getMsg());
e.printStackTrace();//復寫了此方法的
}
}
public static void test() throws StudentExeception{ ?//聲明異常,并沒有處理
throw new StudentExeception("不是Student");//自定義的異常,拋出異常對象
}
}
?HashSet 是 Set 接口的典型實現,大多數時候使用Set 集合時都使用這個實現類。 ?HashSet 按 Hash 算法來存儲集合中的元素,因此具有很好的存取和查找性能。 ?HashSet 具有以下特點: –不能保證元素的排列順序 –HashSet不是線程安全的 –集合元素可以使 null ?當向 HashSet 集合中存入一個元素時,HashSet 會調用該對象的 hashCode() 方法來得到該對象的hashCode 值,然后根據 hashCode 值決定該對象在 HashSet 中的存儲位置。 ?如果兩個元素的 equals() 方法返回 true,但它們的 hashCode() 返回值不相等,hashSet 將會把它們存儲在不同的位置,但依然可以添加成功。
?LinkedHashSet 是 HashSet 的子類 ?LinkedHashSet 集合根據元素的 hashCode 值來決定元素的存儲位置,但它同時使用鏈表維護元素的次序,這使得元素看起來是以插入順序保存的。 ?LinkedHashSet性能插入性能略低于 HashSet,但在迭代訪問 Set 里的全部元素時有很好的性能。 ?LinkedHashSet不允許集合元素重復。
?TreeSet 是 SortedSet 接口的實現類,TreeSet可以確保集合元素處于排序狀態。 ?TreeSet支持兩種排序方法:自然排序和定制排序。默認情況下,TreeSet采用自然排序。
package com.hbut.test;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import com.hbut.domain.Person;
/**
?* Set(接口):放置的元素是按照哈希表來放的,元素是無序的;
?* ? ?注意:1.放置元素時使用對象的equals方法判斷的;
?* ? ? ? ? ? ? ? 2.可以放置null(null其實既不是類,也不是類型 )值,但是只能放一個;
?* ? ?HashSet是Set接口的實現類,是非線程安全的,一般用的比較多,非線程安全可以轉為線程安全的;
?* ? ? ? ?LinkedHashSet:是HashSet的子類,對插入的數據是有序的,他的底層不僅有hash算法,還有鏈表維護,里面也不能有重復的元素。
?* ? ? ? ??
?* ? ?
?*
?*/
public class TestSet {
public static void main(String[] args) {
Set set = new LinkedHashSet();//保證set的有序
set.add(null);
set.add(null);
System.out.println(set.size());
Person person =new Person();
Person person2 =new Person();
System.out.println(person.hashCode()); ? ?//注意:沒有復寫person的hashcode方法的話,那么兩個對象是存在不一樣的地方的。
System.out.println(person2.hashCode());
System.out.println(person.equals(person2));//注意:已經復寫了person的equals方法了
System.out.println(person==person2);
set.add(person);//添加的是同一對象
set.add(person2);
System.out.println(set.size());
set.add(new Person("xx",21)); ?//并未覆寫equals方法,所以是兩個不同的對象,無法比較。如果復寫了,那么就是一個了,去試試
set.add(new Person("xx",21)); ??
System.out.println(set.size());
set.add("hello");
Iterator it = set.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
//對于TreeSet的實驗 package com.hbut.test;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
import com.hbut.domain.Student;
import com.hbut.exeception.StudentExeception;
import com.hbut.util.MyComparator;
public class TestTreeSet {
/**
* 1.如果使用treeSet的無參數構造器來創建對象,那么添加的對象必須實現Comparable接口,復寫compareTo方法,不能放入null,不然會發生空指針異常;
* 2.不能傳不是同一類對象,不然會發生類型轉換異常ClassCastExeception異常
* 3.兩個對象是按照Comparable的接口的comparaTo方法比較,是由TreeSet調用此方法
*?
* (1).要么類實現Comparable接口,復寫ComparaTo方法;
* (2).要么寫一個比較器,Comparator 復寫compare方法;(推薦這種,比較方法,可以直接使用)
*/
public static void main(String[] args) {
// Set st= new TreeSet();
//
// //st.add(null);
//
// st.add("BB"); ?//對放入的元素默認是按照自然順序排序的,元素也是不可重復的,注意:還可以定制的;
// st.add("AA");
// st.add("CC");
//
// st.add("2");
// st.add("1");
// st.add("3");
//
int x=22;
st.add(x);
//
//
// for(Object obj :st){
//
// System.out.println(obj);
//
// }
Set st2= new TreeSet<>();
st2.add(new Student("BB",95));
st2.add(new Student("AA",95));//注意:此時的comparaTo返回的是true,是一樣的分數,放不進去,與equals方法相背,需要注意,一般要求兩個最好返回一樣的值
st2.add(new Student("DD",91));
st2.add(new Student("CC",94));
for(Object obj :st2){
System.out.println(obj);
? ? }
Comparator ct = new MyComparator();
Comparator comparator = new Comparator() {//匿名內部類,這是一個比較器
@Override
public int compare(Object o1, Object o2){
if(o1 instanceof Student && o2 instanceof Student){
Student s1= (Student) o1;
Student s2= (Student) o2;
return s1.getScore()-s2.getScore();
}
else{
throw new ClassCastException("不是Student");
}
}
};
Set s3= new TreeSet<>(ct);
s3.add(new Student("yy",66));
s3.add(new Student("xx",65));
s3.add(new Student("zz",70));
System.out.println("--------用傳入Comparator方法可行------------");
for(Object obj : s3){
System.out.println(obj);
? ? }
try {
test();//需要對異常進行處理。不然直接拋給虛擬機了
} catch (StudentExeception e) {
//System.out.println(e.getMsg());
e.printStackTrace();//復寫了此方法的
}
}
public static void test() throws StudentExeception{ ?//聲明異常,并沒有處理
throw new StudentExeception("不是Student");//自定義的異常,拋出異常對象
}
}
總結
以上是生活随笔為你收集整理的Set集合以及HashSet、LinkedHashSet、TreeSet等讲解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ssh-keygen 的 详解
- 下一篇: List的4种迭代方法