我试图通过排序的地图获取值,并使用比较器返回值nil.
(def tmap {1 {:v 1} 2 {:v 2} 3 {:v 3}})
(def tmap-sorted
(apply sorted-map-by
#(let [val-comp (- (compare
(get-in tmap [%1 :v])
(get-in tmap [%2 :v])))]
(if (= val-comp 0)
1
val-comp))
(flatten (vec tmap))))
; => {3 {:v 3} 2 {:v 2} 1 {:v 1}}
(get tmap-sorted 3)
;=> nil
Run Code Online (Sandbox Code Playgroud)
预期: {:v 3}
实际: nil
您正在创建一个自定义Comparator,compare用于PersistentTreeMap(类型tmap-sorted)查找值,但您的比较器永远不会返回0,这意味着两个对象相等.
https://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html
当使用能够强加与equals不一致的排序的比较器来排序有序集(或有序映射)时,应该谨慎行事.假设带有显式比较器c的有序集(或有序映射)与从集合S中绘制的元素(或键)一起使用.如果由S对S施加的排序与equals不一致,则排序集(或有序映射)将表现得"奇怪".特别是有序集(或有序映射)将违反集合(或映射)的一般契约,其以等于的方式定义.
如果您将比较器修改println为调试,您可以看到,当比较3到3时,您得到1意味着它们不相等.
(def tmap {1 {:v 1} 2 {:v 2} 3 {:v 3}})
(def tmap-sorted (apply
sorted-map-by
#(let [val-comp
(- (compare
(get-in tmap [%1 :v])
(get-in tmap [%2 :v])))
ret (if (= val-comp 0)
1
val-comp)]
(println "%1: " %1 " %2: " %2 " ret=" ret)
ret)
(flatten (vec tmap))))
(get tmap-sorted 3)
;; %1: 3 %2: 2 ret= -1
;; %1: 3 %2: 3 ret= 1
(get tmap-sorted 1)
;; %1: 1 %2: 2 ret= 1
;; %1: 1 %2: 1 ret= 1
Run Code Online (Sandbox Code Playgroud)
所以你需要修复你的compare功能以实现平等