Set實現的超級父類接口:Collection
Set :元素是無序的,元素不可以重複
常見子類:1.HashSet
2.TreeSet
HashSet:它不保證 set 的迭代順序;特別是它不保證該順序恆久不變。此類允許使用 null 元素。 是線程不同步的,底層數據結構是哈希表。
HashSet是如何保證元素唯一性的呢?是通過元素的兩個方法,hasCode和equals來完成的
如果元素的hashCode值相同,纔會判斷equals是否爲true。
如果元素的hashCode值不同,不會調用equals
注意,對於判斷元素是否存在,以及刪除等操作,依賴的方法是元素的hashCode和equals方法,而List只依賴equals方法
import java.util.*;
public class SetDemo {
public static void main(String[] args) {
HashSet hs=new HashSet();
hs.add(new Person("lisi03",23));
hs.add(new Person("lisi007",25));
hs.add(new Person("lisi01",22));
hs.add(new Person("lisi01",22));
Iterator it=hs.iterator();
while(it.hasNext()){
Person p=(Person)it.next();
System.out.println(p.getName()+"..."+p.getAge());
}
}
}
class Person{
private String name;
private int age;
Person(String name,int age){
this.name=name;
this.age=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 boolean equals(Object obj){
if(!(obj instanceof Person))
return false;
Person p=(Person)obj;
System.out.println(this.name+"....equals..."+p.name);
return (this.name.equals(p.name)&&(this.age==p.age));
}
//通過重寫hashCode函數來解決出現相同元素問題
public int hashCode(){
//System.out.println(name+"....");
return (name.hashCode()+age*37);
}
}
TreeSet:可以對Set集合中的元素進行排序。
底層數據結構是二叉樹保證元素唯一性的依據:compareTo方法return 0;
TreeSet排序的第一種方式,讓元素自身具備比較性。元素需要實現Comparable接口,覆蓋compareTo方法,
這中方式也成爲元素的自然順序,或者叫做默認順序。
TreeSet排序的第二中方式,當元素自身不具備比較性時,或者具備的比較性不是所需要的,這時就需要讓集合自身具備比較 性。
在集合初始化時,就有了比較方式。
定義了比較器,將比較器對象作爲參數傳遞給TreeSet集合的構造函數。
當兩中排序都存在時,以比較器爲主。
定義一個類,實現Comparator接口,覆蓋compare方法
package Test;
import java.util.*;
public class practice{
public static void main(String [] args){
TreeSet <Person> ts=new TreeSet<Person>(new Namecompare());
ts.add(new Person(3,"kb"));
ts.add(new Person(1,"kewenjie"));
ts.add(new Person(4,"html"));
ts.add(new Person(2,"wjk"));
ts.add(new Person(2,"kwj"));
Iterator <Person> it=ts.iterator();
while(it.hasNext()){
Person ps=it.next();
System.out.println(ps.getAge()+"...."+ps.getName());
}
}
}
class Person implements Comparable{
private int age;
private String name;
public Person(int id,String name){
this.name=name;
this.age=id;
}
public int getAge() {
return age;
}
public void setId(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int compareTo(Object o){ //覆蓋compareTo方法,實現按年齡順序排列,如果年齡相同,則按照姓名的自然順序排列
if(!(o instanceof Person)){
throw new RuntimeException("不是Person對象");
}
Person ps=(Person)o;
int n=this.age-ps.age;
if(n==0){
return this.getName().compareTo(ps.getName());
}
return n;
}
}
class Namecompare implements Comparator{ //定義比較器,實現按照姓名的自然順序排列,如果年齡相同,則實現按年齡順序排列。
public int compare(Object o1,Object o2){
Person ps1=(Person)o1;
Person ps2=(Person)o2;
int n=ps1.getName().compareTo(ps2.getName());
if(n==0){
return ps1.getAge()-ps2.getAge();
}
return n;
}
}
由於Person類不具備比較性,所以需要實現Comparable接口,並覆蓋compareTo方法,或者定義比較器。