程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 處理TreeSet類的排序成績

處理TreeSet類的排序成績

編輯:關於JAVA

處理TreeSet類的排序成績。本站提示廣大學習愛好者:(處理TreeSet類的排序成績)文章只能為提供參考,不一定能成為您想要的結果。以下是處理TreeSet類的排序成績正文


TreeSet支撐兩種排序辦法:天然排序和定制排序。TreeSet默許采取天然排序。

1、天然排序

TreeSet會挪用聚集元素的compareTo(Object obj)辦法來比擬元素之間年夜小關系,然後將聚集元素按升序分列,這類方法就是天然排序。(比擬的條件:兩個對象的類型雷同)。

java供給了一個Comparable接口,該接口裡界說了一個compareTo(Object obj)辦法,該辦法前往一個整數值,完成該接口的類必需完成該辦法,完成了該接口的類的對象便可以比擬年夜小。當一個對象挪用該辦法與另外一個對象停止比擬,例如obj1.comparTo(obj2),假如該辦法前往0,則注解這兩個對象相等;假如前往一個正整數,則注解obj1年夜於obj2;假如該辦法前往一個負整數,則注解obj1小於obj2.

java經常使用類完成Comparable接口,並供給了比擬年夜小的尺度。完成Comparable接口的經常使用類:

  • BigDecimal、BigIneger和一切數值型對應包裝類:按它們對應的數值的年夜小停止比擬。
  • Character:按字符的UNICODE值停止比擬。
  • Boolean:true對應的包裝類實例年夜於false對應的包裝類實例。
  • String:按字符串中字符的UNICODE值停止比擬。
  • Date、Time:前面的時光、日期比後面的時光、日期年夜。

假如試圖把一個對象添加進TreeSet時,則該對象的類必需完成Comparable接口。

以下法式則會報錯:

class Err 
{ 
} 
public class TestTreeSetError 
{ 
public static void main(String[] args) 
{ 
TreeSet ts = new TreeSet(); 
//向TreeSet聚集中添加兩個Err對象 
ts.add(new Err()); 
ts.add(new Err()); 
} 
} 

解釋:

下面法式試圖向TreeSet聚集中添加2個Err對象,添加第一個對象時,TreeSet裡沒有任何元素,所以沒有成績;當添加第二個Err對象時,TreeSet就會挪用該對象的compareTo(Object obj)辦法與聚集中其他元素停止比擬——假如對應的類沒有完成Comparable接口,則會激發ClassCastException異常。並且當試圖從TreeSet中掏出元素第一個元素時,仍然會激發ClassCastException異常。

當采取compareTo(Object obj)辦法比擬對象時,都須要將被比擬對象obj強迫類型轉換成雷同類型,由於只要雷同類的兩個實例能力比擬年夜小。即向TreeSet中添加的應當是統一個類的對象,不然會激發ClassCastException異常。例如,當向TreeSet中添加一個字符串對象,這個操作完整正常。當添加第二個Date對象時,TreeSet就好挪用該對象的compareTo(Object obj)辦法與聚集中其他元素停止比擬,則此時法式會激發異常。

在現實編程中,法式員可以界說本身的類向TreeSet中添加多品種型的對象,條件是用戶自界說類完成了Comparable接口,完成該接口時在完成compareTo(Object obj)辦法時沒有停止強迫類型轉換。但當操作TreeSet裡的聚集數據時,分歧類型的元素仍然會產生ClassCastExceptio異常。(賣力浏覽下就會明確)

當把一個對象參加TreeSet聚集中時,TreeSet挪用該對象的compareTo(Object obj)辦法與容器中的其他對象比擬年夜小,然後依據紅黑樹算法決議它的存儲地位。假如兩個對象經由過程compareTo(Object obj)比擬相等,TreeSet即以為它們存儲統一地位。

關於TreeSet聚集而言,它斷定兩個對象不相等的尺度是:兩個對象經由過程equals辦法比擬前往false,或經由過程compareTo(Object obj)比擬沒有前往0——即便兩個對象時統一個對象,TreeSet也會把它們當做兩個對象停止處置。

以下法式所示:

//Z類,重寫了equals辦法,老是前往false, 
//重寫了compareTo(Object obj)辦法,老是前往正整數 
class Z implements Comparable 
{ 
int age; 
public Z(int age) 
{ 
this.age = age; 
} 
public boolean equals(Object obj) 
{ 
return false; 
} 
public int compareTo(Object obj) 
{ 
return 1; 
} 
} 
public class TestTreeSet 
{ 
public static void main(String[] args) 
{ 
TreeSet set = new TreeSet(); 
Z z1 = new Z(6); 
set.add(z1); 
System.out.println(set.add(z1)); 
//上面輸入set聚集,將看到有2個元素 
System.out.println(set); 
//修正set聚集的第一個元素的age屬性 
((Z)(set.first())).age = 9; 
//輸入set聚集的最初一個元素的age屬性,將看到也釀成了9 
System.out.println(((Z)(set.last())).age); 
} 
} 

 法式運轉成果:

true
[TreeSet.Z@1fb8ee3, TreeSet.Z@1fb8ee3]
9
解釋:

法式中把統一個對象添加了兩次,由於z1對象的equals()辦法老是前往false,並且compareTo(Object obj)辦法老是前往1。如許TreeSet會以為z1對象和它本身也不雷同,是以TreeSet中添加兩個z1對象。而TreeSet對象保留的兩個元素現實上是統一個元素。所以當修正TreeSet聚集裡第一個元素的age屬性後,該TreeSet聚集裡最初一個元素的age屬性也隨之轉變了。

總結:當須要把一個對象放入TreeSet中時,重寫該對象對應類的equals()辦法時,應包管該辦法與compareTo(Object obj)辦法有分歧成果,其規矩是:假如兩個對象經由過程equals辦法比擬前往true時,這兩個對象經由過程compareTo(Object obj)辦法比擬應前往0。

假如兩個對象經由過程equals辦法比擬前往true,但這兩個對象經由過程compareTo(Object obj)辦法比擬不前往0時,這將招致TreeSet將會把這兩個對象保留在分歧地位,從而兩個對象都可以添加勝利,這與Set聚集的規矩有點收支。

假如兩個對象經由過程compareTo(Object obj)辦法比擬前往0時,但它們經由過程equals辦法比擬前往false時將更費事:由於兩個對象經由過程compareTo(Object obj)辦法比擬相等,TreeSet將試圖把它們保留在統一個地位,但現實上又不可(不然將只剩下一個對象),所以處置起來比擬費事。

假如向TreeSet中添加一個可變對象後,而且前面法式修正了該可變對象的屬性,招致它與其他對象的年夜小次序產生轉變,但TreeSet不會再次調劑它們的次序,乃至能夠招致TreeSet中保留這兩個對象,它們經由過程equals辦法比擬前往true,compareTo(Object obj)辦法比擬前往0.

以下法式所示:

class R 
{ 
int count; 
public R(int count) 
{ 
this.count = count; 
} 
public String toString() 
{ 
return "R(count屬性:" + count + ")"; 
} 
public boolean equals(Object obj) 
{ 
if (obj instanceof R) 
{ 
R r = (R)obj; 
if (r.count == this.count) 
{ 
return true; 
} 
} 
return false; 
} 
public int hashCode() 
{ 
return this.count; 
} 
} 
public class TestHashSet2 
{ 
public static void main(String[] args) 
{ 
HashSet hs = new HashSet(); 
hs.add(new R(5)); 
hs.add(new R(-3)); 
hs.add(new R(9)); 
hs.add(new R(-2)); 
//打印TreeSet聚集,聚集元素是有序分列的 
System.out.println(hs); 
//掏出第一個元素 
Iterator it = hs.iterator(); 
R first = (R)it.next(); 
//為第一個元素的count屬性賦值 
first.count = -3; 
//再次輸入count將看到TreeSet裡的元素處於無序狀況 
System.out.println(hs); 
hs.remove(new R(-3)); 
System.out.println(hs); 
//輸入false 
System.out.println("hs能否包括count為-3的R對象?" + hs.contains(new R(-3))); 
//輸入false 
System.out.println("hs能否包括count為5的R對象?" + hs.contains(new R(5))); 
 
} 
} 
 

法式運轉成果:

[R(count屬性:-3), R(count屬性:-2), R(count屬性:5), R(count屬性:9)]
[R(count屬性:20), R(count屬性:-2), R(count屬性:5), R(count屬性:-2)]
[R(count屬性:20), R(count屬性:-2), R(count屬性:5), R(count屬性:-2)]
[R(count屬性:20), R(count屬性:-2), R(count屬性:-2)]
解釋:

下面法式中的R對象是一個正常重寫了equals辦法和comparable辦法類,這兩個辦法都以R對象的count屬性作為斷定的根據。可以看到法式第一次輸入的成果是有序分列的。當轉變R對象的count屬性,法式的輸入成果也產生了轉變,並且包括了反復元素。一旦轉變了TreeSet聚集裡可變元素的屬性,當再視圖刪除該對象時,TreeSet也會刪除掉敗(乃至聚集華夏有的、屬性沒被修正,但與修正後元素相等的元素也沒法刪除),所以刪除count

為-2的R對象時,沒有任何元素被刪除;法式可以刪除count為5的R對象,這注解TreeSet可以刪除沒有被修正屬性、且不與其他被修正屬性的對象反復的對象。

總結:與HashSet在處置這些對象時將異常龐雜,並且輕易失足。為了讓法式更具硬朗,推舉HashSet和TreeSet聚集中只放入弗成變對象。

2、定制排序

TreeSet的天然排序是依據聚集元素的年夜小,TreeSet將他們以升序分列。假如須要完成定制排序,例如降序,則可使用Comparator接口。該接口裡包括一個int compare(T o1, T o2)辦法,該辦法用於比擬o1和o2的年夜小。

假如須要完成定制排序,則須要在創立TreeSet聚集對象時,並供給一個Comparator對象與該TreeSet聚集聯系關系,由該Comparator對象擔任聚集元素的排序邏輯。

以下法式所示:

class M { 
int age; 
 
public M(int age) { 
this.age = age; 
} 
 
public String toString() { 
return "M對象(age:" + age + ")"; 
} 
} 
 
public class TestTreeSet3 { 
public static void main(String[] args) { 
TreeSet ts = new TreeSet(new Comparator() { 
public int compare(Object o1, Object o2) { 
 
M m1 = (M) o1; 
M m2 = (M) o2; 
 
if (m1.age > m2.age) { 
return -1; 
} else if (m1.age == m2.age) { 
return 0; 
} else { 
return 1; 
} 
} 
}); 
ts.add(new M(5)); 
ts.add(new M(-3)); 
ts.add(new M(9)); 
System.out.println(ts); 
} 
} 
 

法式運轉成果:

[M對象(age:9), M對象(age:5), M對象(age:-3)]
解釋:

下面法式中創立了一個Comparator接口的匿名外部類對象,該對象擔任ts聚集的排序。所以當我們把M對象添加到ts聚集中時,不必M類完成Comparable接口,由於此時TreeSet不必經由過程M對象來比擬年夜小,而是由與TreeSet聯系關系的Comparator對象來擔任聚集元素的排序。應用定制排序時,TreeSet對聚集元素排序時不論聚集元素自己的年夜小,而是由Comparator對象擔任聚集元素的排序規矩。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved