java中Set集合
/** * Set:元素不可以重複,是無序的 * Set接口中的方法和Collection一致 * Set有兩個最重要的子類HashSet,TreeSet * HashSet:內部數據哈希表,是不同步的,它不保證 set 的迭代順序;特別是它不保證該順序恆久不變。此類允許使用 null 元素。 * 如何保證該集合的元素唯一性呢? * 是通過對象的hashCode()和equals()方法來完成對象唯 一性的 * 如果對象的hashCode()值不同,那麼不用判斷equals方法,就直接存儲到哈希表中 * 如果對象的hashCode值相同,那麼要再次判斷對象 的equals方法是否爲true * 如果爲true,視爲相同元素,不存。如果爲false,那麼視爲不同元素,就進行存儲。 * * 記住:如果元素要存儲到HashSet集合中,必須覆蓋hashCode方法和equals方法。 * 一般情況 下,如果定義的類會產生很多對象 ,比如 人,學生,書,通常都 需要覆蓋equals,hashCode方法。 * 建立對象判斷是否相同的依據 * TreeSet:可以對Set集合中的元素進行指定順序的排序。是不同步 的。 * 判斷元素唯一性的方式 :就是根據比較方法comperTo(),返回結果是否是0,是0,就是相同元素,則不往裏存儲 * *
TreeSet對元素進行排序的方式 一: * 讓元素自身具備比較功能,元素需要實現 Comparable接口,重寫compeareTo方法 * 如果不要按照對象中具備 的自然順序進行排序,如果對象 中不具備 自然順序,怎麼辦? * 可以使用TreeSet集合第二種排序方式 二: * 讓集合自身具備比較功能,定義一個類實現 Comparator接口,重寫compare方法 * 將該 類對象作爲參數傳遞給TreeSet集合的構造函數* * LinkedHashSet是HashSet的子類,它是有序的,且不可重複 *///arrayList判斷元素是否相同 remove(),contains(),的依據是equals()方法,//HashSet的依據是hashCode()和equals()方法,該元素是否有和該容器中的元素相同//所以對於自定義對象,如果利用ArrayList容器進行存儲,一定要重寫equals()方法,//所以對於自定義對象,如果利用HastSet容器進行存儲,一定要重寫HashCode()和equals()方法,//往HashSet集合中存儲Person對象,如果姓名和年齡相同,視爲同一個人,視爲相同元素
public class Person implements Comparable { private String name; private int age; public 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; } @Override public int hashCode() {//判斷hash值是否相同 // System.out.println(this+"......hashcode..."); return name.hashCode() + age; } @Override public boolean equals(Object obj) {//判斷內容是否相同 if (this == obj) { return true; } if (!(obj instanceof Person)) { throw new ClassCastException("類型轉換錯誤"); } // System.out.println(this + "......equals...." + obj); Person person = (Person) obj; return this.name.equals(person.name) && this.age == person.age; } @Override public String toString() { return name + ":" + age; } @Override public int compareTo(@NonNull Object o) { Person person = (Person) o;
//主要是按年齡排序,如果年齡相同,根據姓名進行自然排序
int temp = this.age - person.age; return temp == 0 ? this.name.compareTo(person.name) : temp;
}
}//HashSetDemo
public class HashSetDemo {
public static void main(String[] args) { HashSet hashSet = new HashSet();
//下面使用LinkedHashSet,它是有序的,不可重複的
// HashSet hashSet = new LinkedHashSet();
hashSet.add(new Person("aaa", 10));
hashSet.add(new Person("bbb", 20));
hashSet.add(new Person("bbb", 20));
hashSet.add(new Person("ccc", 30));
hashSet.add(new Person("ccc", 30));
Iterator iterator = hashSet.iterator();
while (iterator.hasNext()) {
Person person = (Person) iterator.next();
System.out.println(person.getName() + "," + person.getAge());
}
}
}//TreeSetDemopublic class TreeSetDemo { public static void main(String[] args){ demo1(); demo2(); } //存自定義對象 private static void demo2() { TreeSet treeSet = new TreeSet(); treeSet.add(new Person("zhangsan", 10)); treeSet.add(new Person("lisi", 20)); treeSet.add(new Person("wangwu", 20)); treeSet.add(new Person("wangwu", 20)); treeSet.add(new Person("zhaoliu", 30)); treeSet.add(new Person("zhouqi", 30)); Iterator iterator = treeSet.iterator(); while (iterator.hasNext()) { Person person = (Person) iterator.next(); System.out.println(person.getName() + "," + person.getAge()); } } //存字符串 private static void demo1() { TreeSet treeSet = new TreeSet(); treeSet.add("aaa"); treeSet.add("nbb"); treeSet.add("ecc"); treeSet.add("gcc"); treeSet.add("kdd"); Iterator iterator = treeSet.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } } }//方式 二 Comparator的運用,它的原理是二叉樹
* 創建了一個根據Person類的name進行排序的比較器 */ public class ComparatorByName implements Comparator { @Override public int compare(Object o, Object t1) { Person person = (Person) o; Person person1 = (Person) t1; int temp = person.getName().compareTo(person1.getName()); return temp == 0?person.getAge()-person1.getAge():temp; // return 1;//這樣是有序排,怎麼存,怎麼取 // return -1;//這樣是有序排,怎麼存,反過來取 } }
//下面是運用自定義比較器,存自定義對象 private static void demo2() { TreeSet treeSet = new TreeSet(new ComparatorByName());//這樣存進去Person類就不用實現Comparable接口 treeSet.add(new Person("zhangsan", 10)); treeSet.add(new Person("lisi", 20)); treeSet.add(new Person("wangwu", 20)); treeSet.add(new Person("wangwu", 20)); treeSet.add(new Person("zhaoliu", 30)); treeSet.add(new Person("zhouqi", 30)); Iterator iterator = treeSet.iterator(); while (iterator.hasNext()) { Person person = (Person) iterator.next(); System.out.println(person.getName() + "," + person.getAge()); } }
//對字符串長度進行比較排序 public class ComparatorByLength implements Comparator { @Override public int compare(Object o, Object t1) { String s1 = (String) o; String s2 = (String) t1; int temp = s1.length()-s2.length(); return temp==0?s1.compareTo(s2):temp; } }
//運用字符串長度進行比較排序 存字符串
private static void demo1() { TreeSet treeSet = new TreeSet(new ComparatorByLength()); treeSet.add("aaa"); treeSet.add("nbbdd"); treeSet.add("ecdc"); treeSet.add("gcad"); treeSet.add("kdeterfd"); Iterator iterator = treeSet.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } }