我尝试通过排序地图中的键获取值,使用比较器按值返回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
预期:{:v 3}
实际:nil
答案 0 :(得分:5)
您正在使用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
因此,您需要修复compare
函数以实现平等