繁体   English   中英

在java中覆盖“等于”的clojure相当于什么?

[英]What is the clojure equivalent of Overriding “equals” in java?

我最近在clojure中询问了地图中的复合键: 如何在clojure中实现复合键? ...

答案是它们的工作方式类似于java键 - 如果某些事情覆盖“等于”,那么它可以有效地用作键。

我想知道:是否有宏允许我们覆盖自定义数据结构的“等于”? 例如,假设我想使用Map作为键,并将唯一性定义为“如果此映射包含与另一个映射共同的2个或更多元素,则它们是相等的”。 我怎样才能覆盖地图的默认行为?

在java中,我发现这个工具在制作带有数千个bean作为键的高速地图时非常强大。

为了有希望在本次讨论中增加一些清晰度,在Java中,通常会覆盖hashCodeequals 例如,您正在尝试跟踪具有名称但可能还有昵称的员工。 目标是确保这些员工不会重复。 在这种情况下,我会覆盖equalshashCode ,只查看员工的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中通过使用自定义SortedMapsorted-map (或分别为SortedMap )来做类似的事情。 但是,如果你选择一个实际上没有实现相等性的比较器而是某种“模糊相等”,那么就会有数以万计的陷阱。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM