[英]What is the clojure equivalent of Overriding “equals” in java?
为了有希望在本次讨论中增加一些清晰度,在Java中,通常会覆盖hashCode
和equals
。 例如,您正在尝试跟踪具有名称但可能还有昵称的员工。 目标是确保这些员工不会重复。 在这种情况下,我会覆盖equals
和hashCode
,只查看员工的ID。 当这些员工进入Set数据结构时,它们不会重复。 在Clojure中,您可以这样做:
(deftype Employee [name id]
Object
(equals [a b] (= (.id a) (.id b)))
(hashCode [this] (.hashCode (.id this)))
(toString [this] (.name this)))
(def vince (Employee. "Vince" 42))
(def vincent (Employee. "Vincent" 42))
(def tony (Employee. "Tony" 2))
(into #{} [vince vincent tony])
但是你可能希望采用“纯Clojure”数据结构解决方案而不是去哈希码,等于Java互操作之路。
不是clojure集合重写等于; 在你做一些有趣的事情的几乎每个地方都会发生压倒一切的平等。 Clojure类型提供了equals的实现,这些实现旨在与整个语言保持一致(可以说是打算使用Java等于的方式)。 这意味着“相等”的东西应该是集合中的单个项目,而地图中的单个密钥,总是在任何地方 。 语言设计取决于此。 Clojure 1.3做了一些明确的非向后兼容的更改,以更接近理想。
不管怎么说,违背平等的预期行为很可能会在某处造成麻烦。 当你真正需要它们时,使用你自己的类似组合的复合材料并不是太困难,而不必强迫你的核心等于你的意志。
也就是说,如果你真的想要,你可以使用许多java互操作函数和宏来变换equals系统。 请参阅http://clojure.org/datatypes作为起点。
这在Clojure和Java中都很疯狂。 不要这样做 。 你将破坏Object类和Map接口的契约; 如果他们使用你的自定义地图类,那么各种事情都会完全崩溃。 如果你声明两个对象是equal
那么它们的哈希码必须是相同的,否则持有它们的HashMap将无法应对。 当然,你可以将所有哈希值设为0,但是你的高性能地图 - 它现在是一个链表。
也就是说,你可以在Clojure或Java中通过使用自定义SortedMap
的sorted-map
(或分别为SortedMap
)来做类似的事情。 但是,如果你选择一个实际上没有实现相等性的比较器而是某种“模糊相等”,那么就会有数以万计的陷阱。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.