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

jay*_*100 5 java hashtable clojure

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

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

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

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

Jul*_*ang 5

为了有希望在这个讨论中增加一些清晰度,在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])
Run Code Online (Sandbox Code Playgroud)

但是你可能希望采用"纯Clojure"数据结构解决方案而不是去哈希码,等于Java互操作之路.


Joo*_*aat 4

这并不是 clojure 集合重写了equals;而是 clojure 集合重写了 equals。覆盖 equals 几乎发生在你做一些有趣的事情的任何地方。Clojure 类型提供了 equals 的实现,旨在使整个语言保持一致(可以说以 Java 的 equals 的使用方式)。这意味着“相等”的事物应该是集合中的单数项,以及映射中的单数键,始终、无处不在。语言设计取决于此。Clojure 1.3 做了一些明确的非向后兼容的更改以更接近这一理想状态。

违背平等的预期行为很可能会在某个地方、以某种方式引起麻烦。当你真正需要它们时,使用你自己的类似集合的复合材料并不太困难,而不必将你的意志强加在核心平等上。

也就是说,如果您确实愿意,可以使用许多 Java 互操作函数和宏来破坏 equals 系统。请参阅http://clojure.org/datatypes作为起点。