Set是Collection的子介面,與它同級的介面還有List、Queue;
關於Set,它的顯著性特徵就是,無法記錄數據儲存的先後順序,無法儲存重複元素進入數據集合;
接下來介紹下HashSet與TreeSet
無序性、單元性
通過了兩個判斷,第一個:通過HashCode;第二個:通過equals完成;
更近一步解釋的:
(1)當我們建立出了一個新的HashSets,向內傳入數據時,我們需要計算出HashCode值出來,計算方式我們可以自定義。
(2)將新傳入的數據計算出HashCode值,之後與集合內的每個進行比較,會出現兩種情況:
A:新HashCode值未出現,則直接將新值插入到集合。
B:新HashCode值出現過,則進行equals判斷,將新插入元素與已存在的元素進行equals判斷,這時也會出現兩種結果:
C:返回ture,兩個元素相同,則不會插入新值。
D:返回False,兩個元素雖然HashCode值相同,但是元素本身並不相同,選擇插入新元素。
import java.util.HashSet;
import java.util.Iterator;
class hashSetDemo
{
public static void main(String[] args)
{
HashSet a = new HashSet();
a.add(new Person("wangziyu01", 23));
a.add(new Person("wangziyu01", 23));// 重複
a.add(new Person("wangziyu02", 24));
a.add(new Person("wangziyu03", 25));
a.add(new Person("wangziyu04", 26));
a.add(new Person("wangziyu04", 26));// 重複 hashset重複元素進行兩次判斷:hashCode值判斷+equals內容判斷
Iterator it = a.iterator();
while (it.hasNext())
{
Person p = (Person)it.next();
sop(p.getName()+"..."+p.getAge());// 列印結果
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
class Person // 定義 equals比較方法 + hashCode計算方法
{
private String name;
private int age;
Person(String name, int age)
{
this.name = name;
this.age = age;
}
public boolean equals(Object obj) //定義equals比較方法
{
if(!(obj instanceof Person))
return false;
Person p = (Person)obj;
System.out.println(this.name+"..hashCode相同時,執行equals比較內容.."+p.name);
return this.name.equals(p.name) && this.age == p.age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public static void sop(Object obj)
{
System.out.println(obj);
}
public int hashCode() { //定義hashCode計算方法
System.out.println(this.name + "....計算hashCode");
return name.hashCode() + age * 37;
}
}
最後列印出來的結果解釋:
wangziyu01…計算hashCode
wangziyu01…計算hashCode
wangziyu01…hashCode相同時,執行equals比較內容…wangziyu01 // equals比較結果相同,進行剔除
wangziyu02…計算hashCode
wangziyu03…計算hashCode
wangziyu04…計算hashCode
wangziyu04…計算hashCode
wangziyu04…hashCode相同時,執行equals比較內容…wangziyu04 // equals比較結果相同,進行剔除
最終結果:
wangziyu04…26
wangziyu01…23
wangziyu03…25
wangziyu02…24
(1)數據結構爲雜湊表,執行緒爲非同步
(2)保證元素唯一性的原理:判斷元素的hashCode值是否相同,如果相同,還會繼續判斷元素的equals方法,是否爲true。
(3)HashCode的計算方法與equals方法可以在物件中自定義,而不需要管如何呼叫,它是自動的
(4) HashSet數據集無法記錄儲存順序。
(5)HashSet數據集無法儲存相同元素。
基本介紹:TreeSet是Set下子類,TreeSet會對傳入的數據進行排序。
TreeSet的底層數據爲二元樹結構,使用到了compareTo方法return 0;來保證元素的唯一性。
需要讓數據具有可比性:
(1)方式一:讓元素自身具備比較性。
解釋:元素自身實現Compareable介面(例如:學生物件的數據,讓它實現可比性),之後覆蓋compareTo方法,在這個方法中指定返回值,比較無非三種情況:當新加入數據比較結果較大時,返回1;當新加入數據比較結果較小時,返回-1;相同時返回0;
下面 下麪是方式一的體現結果,讓Person具有可比性:
class TreeSetDemo
{
public static void main(String[] args)
{
TreeSet 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;
}
}
列印結果爲:
lisi02…compareto…lisi02
lisi007…compareto…lisi02 // 插入元素與集合已存在的進行比較
lisi09…compareto…lisi02
lisi09…compareto…lisi007
lisi08…compareto…lisi007
lisi08…compareto…lisi09
lisi007…compareto…lisi007 //查詢到了相同的元素準備插入,
lisi02…22
lisi007…20
lisi08…19
lisi09…19
(2)方式二:讓集合自身具備比較性。
解釋:當元素自身不具備比較性時,或者具備的比較性不是所需要的,在集合初始化時,就有了比較方式。