如何从HashSet获取()特定元素?科特林

时间:2020-03-06 00:03:21

标签: android kotlin hashset

假设myHashSet = HashSet<SomeClass>,其中SomeClass.hashcode () = someField.hashcode()

如何返回具有指定哈希码的元素,即:

myHashSet.getElementWithHashCode((other as SomeClass).someField.hashcode())

HashSetother中的元素是具有不同属性值(someField值除外)的不同对象。

奇怪的是,HashSet中没有这样的功能。之前没有人需要吗?最快的方法是什么?

2 个答案:

答案 0 :(得分:1)

我不知道您是否可以使用this,这取决于它在内部使用hashCode还是equals。一些sources在线用户也遇到类似的问题,他们正在寻找基于等号的解决方案。

无论如何,您可以使用findfirst之类的内置函数自己实现它:

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()作为键

不。这个想法是:

  1. set包含"a"(哈希码1;不是真的,但在此示例中假设是),"b"(哈希码1),和"c"(哈希码2)。

  2. 然后map"a": "a", "b": "b", "c": "c"

  3. 致电findByHashCode(1) = map[HasHash(1)]

  4. HasHash(1)的哈希码为1,因此它查找包含键"a""b"的插槽(以该顺序说)。 HasHash(1).equals("a")返回true,因此返回了用键"a"存储的值,即"a"

或getElement()函数是否根据输入元素的哈希码自动检查?

它说的是

从集合中返回等于element的元素;如果找不到此类元素,则返回null。

因此它应该返回"a" 如果按顺序HasHash(1).equals("a")比较它们。