假设myHashSet = HashSet<SomeClass>
,其中SomeClass.hashcode () = someField.hashcode()
如何返回具有指定哈希码的元素,即:
myHashSet.getElementWithHashCode((other as SomeClass).someField.hashcode())
HashSet
和other
中的元素是具有不同属性值(someField
值除外)的不同对象。
奇怪的是,HashSet中没有这样的功能。之前没有人需要吗?最快的方法是什么?
答案 0 :(得分:1)
我不知道您是否可以使用this,这取决于它在内部使用hashCode
还是equals
。一些sources在线用户也遇到类似的问题,他们正在寻找基于等号的解决方案。
无论如何,您可以使用find
或first
之类的内置函数自己实现它:
fun <E> HashSet<E>.findByHashCode(other: E): E? = firstOrNull { it.hashCode() == other.hashCode() }
答案 1 :(得分:1)
没有标准解决方案;但是由于HashMap.get(key)
指定将参数与存储的键(key.equals(k)
进行比较,而不是相反,因此您可以通过这种讨厌的技巧(讨厌的原因是因为它破坏了equals
合同):
class HasHash(private val hash: Int) {
override fun hashCode() = hash
override fun equals(other: Any?) = other != null && other.hashCode() == hash
}
但是即使这样,JVM上的HashSet
也不会暴露您需要的细节(例如getElement
in Kotlin/Native),所以我唯一能想到的解决方案是
val set: HashSet<T> = ...
val map: Map<Any, T> = set.associateBy { it }
fun findByHashCode(hash: Int): T? = map[HasHash(hash)]
它需要遍历set
来构造map
,但只能循环一次,因此如果需要在单个集合中找到许多元素,它仍然很有用。
在Kotlin / Native中只是
fun <T> HashSet<T>.findByHashCode(hash: Int): T? = getElement(HasHash(hash))
另外,如果集合中有多个具有所需哈希码的元素,您将只得到其中之一。
那么您要映射每个项目并将其自身作为键?这是否意味着associateby {}自动将元素的hashcode()作为键
不。这个想法是:
说set
包含"a"
(哈希码1
;不是真的,但在此示例中假设是),"b"
(哈希码1
),和"c"
(哈希码2
)。
然后map
是"a": "a", "b": "b", "c": "c"
。
致电findByHashCode(1) = map[HasHash(1)]
。
HasHash(1)
的哈希码为1
,因此它查找包含键"a"
和"b"
的插槽(以该顺序说)。 HasHash(1).equals("a")
返回true
,因此返回了用键"a"
存储的值,即"a"
。
或getElement()函数是否根据输入元素的哈希码自动检查?
它说的是
从集合中返回等于element的元素;如果找不到此类元素,则返回null。
因此它应该返回"a"
如果按顺序HasHash(1).equals("a")
比较它们。