【Java類集】_排序及重複元素說明筆記
本章目標:
掌握TreeSet的排序原理
掌握Set介面中重複元素的定義
3.具體內容:
TreeSet類的內容是可以排序的,那麼現在我任意給出一個類,觀察能否進行排序的操作。
import java.util.Set;import java.util.TreeSet;class Person{ private String name; private int age; public Person(String name,int age){ this.name = name; this.age = age; } public String toString(){ return "姓名:"+this.name+";年齡:"+this.age; }}public class TreeSetDemo02{ public static void main(String args[]){ Set<Person> allSet = new TreeSet<Person>(); allSet.add(new Person("張三",30)); allSet.add(new Person("李四",31)); allSet.add(new Person("王五",31)); allSet.add(new Person("王五",32)); allSet.add(new Person("趙六",33)); allSet.add(new Person("孫七",34)); allSet.add(new Person("張三",35)); System.out.println(allSet); }}
執行時出現了以下的錯誤:
Exception in thread "main" java.lang.ClassCastException: Person cannot be cast t
o java.lang.Comparable
at java.util.TreeMap.put(Unknown Source)
at java.util.TreeSet.add(Unknown Source)
at TreeSetDemo02.main(TreeSetDemo02.java:22)
修改代碼如下:
import java.util.Set;import java.util.TreeSet;class Person implements Comparable<Person>{ private String name; private int age; public Person(String name,int age){ this.name = name; this.age = age; } public String toString(){ return "姓名:"+this.name+";年齡:"+this.age+"\n"; } public int compareTo(Person per){//此方法一定要與equals區分開,雖然容易混淆 if(this.age>per.age){ return 1; }else if(this.age<per.age){ return 0; }else{ return this.name.compareTo(per.name);//調用String中的compareTo()方法 } }}public class TreeSetDemo02{ public static void main(String args[]){ Set<Person> allSet = new TreeSet<Person>(); allSet.add(new Person("張三",30)); allSet.add(new Person("李四",31)); allSet.add(new Person("王五",31)); allSet.add(new Person("王五",32)); allSet.add(new Person("趙六",33)); allSet.add(new Person("孫七",34)); allSet.add(new Person("張三",35)); System.out.println(allSet); }}
此時,去掉的重複元素並不是真正意義上的重複元素的取消。
import java.util.Set;import java.util.HashSet;class Person{ private String name; private int age; public Person(String name,int age){ this.name = name; this.age = age; } public String toString(){ return "姓名:"+this.name+";年齡:"+this.age+"\n"; }}public class TreeSetDemo03{ public static void main(String args[]){ Set<Person> allSet = new HashSet<Person>(); allSet.add(new Person("張三",30)); allSet.add(new Person("李四",31)); allSet.add(new Person("王五",32)); allSet.add(new Person("王五",32)); allSet.add(new Person("趙六",33)); allSet.add(new Person("孫七",34)); allSet.add(new Person("張三",35)); System.out.println(allSet); }}
此時,並沒有去掉重複的元素,那麼重複元素該如何去掉呢?
如果要想取消掉重複元素,則需要Object類中的兩個方法協助:
hashCode(); 表示一個唯一的編碼,一般通過計算表示。
equals(); 進行對象的比較操作。
import java.util.Set;import java.util.TreeSet;class Person{ private String name; private int age; public Person(String name,int age){ this.name = name; this.age = age; } public String toString(){ return "姓名:"+this.name+";年齡:"+this.age; } public boolean equals(Object obj){//覆寫equals,完成對象比較 if(this==obj){ return true; } if(!(obj instanceof Person)){ return false; } Person p = (Person)obj;//向下轉型 if(this.name.equals(p.name)&&this.age==p.age){ return true; }else{ return false; } } public int hashCode(){ return this.name.hashCode()*this.age; } public String toString(){ return "姓名:"+this.name+";年齡:"+this.age; }}public class RepeatDemo02{ public static void main(String args[]){ Set<Person> allSet = new HashSet<Person>(); allSet.add(new Person("張三",30)); allSet.add(new Person("李四",31)); allSet.add(new Person("王五",32)); allSet.add(new Person("王五",32)); allSet.add(new Person("趙六",33)); allSet.add(new Person("孫七",34)); allSet.add(new Person("張三",35)); System.out.println(allSet); }}
如果要想使用Set,則就必須注意以上的兩個問題。
4.總結:
1.之前曾經強調過,一個好的類應該覆寫Object類中的equals()、hashCode()、toString()三個方法,實際上在String中已經全部覆寫完成了。
2.Set介面依靠hashCode()和equals()完成重複元素的判斷,關於這一點在日後的Map介面中也有體現
3.TreeSet依靠Comparable介面完成排序的操作(需覆寫CompareTo()方法)。