[英]Comparator Data Structure ordering - how to maintain insertion order whilst ordered on another field?
我有一個數據結構,該數據結構需要一個可選的Comparator
來自定義排序(在這種情況下,它是一個TreeSet
但實際上沒關系,我可以換出PriorityQueue
而不破壞我的代碼)。 目前,它是按現場price
對存儲結構的對象進行排序的。
當2個對象的價格相同時,我希望timestamp
成為平局,時間戳為System.CurrentTime
。 要在比較器中指定此設置,我必須使用:
if (Object1.getPrice == Object2.getPrice && Object1.Timestamp > Object2.Timestamp) return 1
問題是,當我執行TreeSet.floor()
或TreeSet.ceiling()
時,這將打破相等的情況-該方法不再識別出兩個對象的價格相同,但是仍然可以識別價格的高低。 我該如何緩解呢?
使用Comparator
您可以確定集合的順序(實際上以及它們的“唯一性”!)。
因此, 您必須確定對象是否相等:
對於這種不同的用法使用不同的數據結構可能是一個選擇,或者可能涵蓋這兩者。 取決於其他要求和代碼邊界。
在這里看看: https : //docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html
基於TreeMap的NavigableSet實現。 元素使用其自然順序進行排序,或通過在設置創建時提供的Comparator進行排序 ,具體取決於所使用的構造函數。
因此,您提供了比較器。
請注意, 如果要正確實現Set接口,則集合(無論是否提供顯式比較器)所維護的順序必須與equals一致 。 (有關與equals一致的精確定義,請參見Comparable或Comparator。)之所以這樣,是因為Set接口是根據equals操作定義的,但是TreeSet實例使用其compareTo(或compare)方法執行所有元素比較 ,因此兩個從集合的角度來看,此方法認為相等的元素是相等的。
因此,如果Set中已經存在一個equals
對象(咨詢比較器),則需要再次添加該對象, 因為它將根據順序放置在Set中相同的位置 (如果您不喜歡這樣做,請不要使用一套)。 它們應實現一致(即使不是編譯器強行強制執行的)。 因此,不是使用直接equals
而是使用比較器。
在內部,比較器可以使用對象的equals
運算符(在if語句中,例如if(obj1.equals(obj2)){return 0;}
)。
但是如何實現equals
-在內部它將取決於一些屬性比較(就像您現在在比較器中所做的那樣)。
如果您不喜歡數據結構,則不要使用(Tree)Set。 根據需要,可以使用地圖或列表。
選擇正確的集合: http : //www.javapractices.com/topic/TopicAction.do? Id= 65
對於==
和equals
之間的差異:
==
正在比較引用,可以說指向容器的指針,如果為true,則是同一實例。 equals
正在比較對象,可以說對象容器的內容,如果為true,則它具有相同的值(在其屬性中) 但是外面可能有數以百萬計的精疲力竭的文章。
注: equals
對象應實現與的hashCode()方法是一致的。 對於(Tree)Set,比較器應實現與equals
一致(可以使用諸如if(obj1.equals(obj2)){return 0;}
)。 此外,其他Set
實現為此使用hasCode()。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.