java集合——树集(TreeSet)+对象的比较
【0】README
0.1) 本文描述轉自 core java volume 1, 源代碼為原創,旨在理解 java集合——樹集(TreeSet)+對象的比較 的相關知識;
0.2) for full source code, please visit https://github.com/pacosonTang/core-java-volume/blob/master/chapter13/TreeSetTest.java
0.3) for java.lang.Comparable 和 java.util.Comparator 的區別和聯系:
http://blog.csdn.net/pacosonswjtu/article/details/50320775 + http://blog.csdn.net/pacosonswjtu/article/details/50320887
【1】樹集(TreeSet)(用到了紅黑樹)
1.1)樹集是一個有序集合。可以以任意順序將元素插入到集合中, 在對集合進行遍歷時,每個值將自動地按照排序后的順序呈現;
- 1.1.1)看個荔枝:
1.1.2)將元素添加到 樹(TreeSet)中要比添加到散列表(HashSet)中慢, 但是,與將元素添加到數組或鏈表的正確位置上相比還是快很多的;
Attention) TreeSet 的排序功能用到了紅黑樹, 因此迭代器總是以排好序的順序訪問每個元素)
【2】對象的比較
2.1) TreeSet如何知道希望元素怎樣排列呢? 在默認情況下, 樹集假定插入的元素實現了 Comparable 接口, 這個接口定義了一個方法:
public interface Comparable<T> {in compareTo(T other); }- 2.1.1)排序后,a在b的前面,后面或相等,分別返回 負值,正值,0;
- 2.1.2)有些標準的 java 平臺類實現了 Comparable接口,如, String類, 這個類的compareTo() 方法依據字典順序對字符串進行比較;
2.2)如果要插入自定義對象, 就必須通過實現 Comparable接口自定義排列順序。
- Attention)在 Object類中, 沒有提供任何 compareTo 接口的默認實現 (干貨);
- 2.2.1)看個荔枝:(展示了如何用部件編號對 Item 對象進行排序)
- Warning)只有整數在一個足夠小的范圍內,才可以使用這個技巧。 如果x是一個較大的正整數, y是一個較大的負整數, x-y 有可能會溢出;
2.3)出現的問題+解決方法
- 2.3.1)出現的問題:使用 Comparable接口定義排列排序顯然有其局限性。對于一個給定的類, 只能實現這個接口一次。如果在一個集合中需要按照部件編號進行排序, 在另一個集合中 卻要按照描述信息進行排序, 該怎么辦呢?還有,如果需要對一個類的對象進行排序, 而這個類的創建者又沒有實現 Comparable接口, 又該怎么辦呢?
- 2.3.2)解決方法: 通過將 Comparator 對象傳遞給TreeSet構造器來告訴樹集使用不同的比較方法。 Comparator接口聲明了一個帶有兩個顯式參數的compare 方法:
- (即, 當兩個不同集合中的元素的排序規則不同, 就要引入Comparator)
- 2.3.2.1)與 compareTo() 方法一樣,a在b之前,之后,或相等, 分別返回 正值, 負值和零;所以,我們直接定義一個 實現 Comparator 接口的類:
- 2.3.2.2)然后將這個類對象傳遞給樹集的構造器:
Attention)
- A1) 注意, 這個比較器沒有任何數據, 它只是比較方法的持有器。有時將這種對象稱為函數對象。
- A2)函數對象通常動態定義, 即定義為匿名內部類的實例:
Annotation)
- A1)實際上, Comparator 接口聲明了兩個方法:compare 和 equals;
- A2)當然,每個類都有一個 equals 方法, 因此, 為這個接口聲明再添加一個 equals 方法似乎沒有太大的好處;
- A3) API文檔說, 不需要覆蓋equals 方法, 但這樣做可能會在某些情況下 提高性能;
2.4)下面的圖是否給了我們的疑慮:是否總應該用 樹集(TreeSet)取代散列集(HashSet)?
- 2.4.1)因為添加一個元素所花費的時間看上去并不很長, 而且元素時自動排序的;
- 2.4.2)到底應該怎樣做將取決于 所要收集的數據。如果不需要對數據進行排序,就沒有必要付出排序開銷 (干貨,如何選擇集類型, 是樹集TreeSet 還是 散列集 HashSet)。
- 2.4.3)更重要的是, 對其排序要比 散列函數更加困難, 因為散列函數只是將對象適
2.5)收集矩形集(just for coarse understanding):想具體了解樹集和散列集間的差異, 還需要研究一個收集矩形集的任務。如果使用 TreeSet, 就需要提供 Comparator;
- 2.5.1)如何比較兩個矩形呢? 比較面積嗎。這行不通。可能會有兩個不同的矩形, 它們的坐標不同, 但面積卻相同。 樹的排序必須是全序的。也就是說, 任意兩個元素是可比的,并且只有在兩個元素相等時才return 0;
- 2.5.2)確實, 有一種矩形的排序方式, (按照坐標的字典順序排序), 但它的計算很牽強且很繁瑣。 相反地, Rectangle 類已經定義了散列函數, 它直接對坐標進行散列;
Annotation) 從 Java SE 6 開始, TreeSet 類實現了 NavigableSet 接口。 這個接口增加了幾個便于定位元素以及反向遍歷的方法;
2.6)看個荔枝:(下面的程序創建了兩個 Item 對象的樹集, 第一個按照部件編號排序, 這是Item對象的默認順序。第二個通過使用一個定制的比較器來按照描述信息排序-)
Complementary)我們給出 Integer 源碼 的 Comparatable 實現:
java.lang.Comparable<T> 1.2 int compareTo(T other) :將this 和 other 進行比較, 返回 正值、負值和0;java.util.Comparator<T> 1.2 int compare(T a, T b): 將a 和 b進行比較, 返回 正值、負值和0;java.util.SortedSet<T> 1.2 Comparator<? super E> comparator() :返回用于對元素進行排序的比較器, 如果元素用 Comparable 接口的compareTo 方法比較則返回 null; E first(); E last(); 返回有序集中的最小最大元素;java.util.NavigableSet<E> 6 E higher(E value) E lower(E value) 返回大于 value 的最小元素或小于 value 的最大元素,否則返回 null;E ceiling(E value) E floor(E value) 返回大于等于 value 的最小元素或小于等于 value 的最大元素,否則返回 null;E pollFirst(E value) E pollLast(E value) 刪除并返回這個集中的最大元素或最小元素, 這個集為空時返回 null;Iterator<E> descendingIterator():返回一個按照 遞減順序遍歷集合中元素的迭代器;java.util.TreeSet<E> 1.2 TreeSet() :構造一個用于 排列 Comparable 對象的樹集; TreeSet(Comparator<? super E > c ):構造一個樹集, 并使用指定的比較器對其中的元素進行排序; TreeSet(SortedSet<? extends E> elements):構造一個樹集, 將有序集中的所有元素添加到這個樹集中, 并使用與給定集合相同的元素比較器;
總結
以上是生活随笔為你收集整理的java集合——树集(TreeSet)+对象的比较的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 次日是指今天还是明天阿 次日是什么意思
- 下一篇: Comparable and Compa