如何从 HashSet 中获取()特定元素?科特林
How to get() specific element from HashSet? Kotlin
假设myHashSet = HashSet<SomeClass>
其中 SomeClass.hashcode() = someField.hashcode()
如何 return 具有指定哈希码的元素,即:
myHashSet.getElementWithHashCode((other as SomeClass).someField.hashcode())
other
和 HashSet
内的对象是不同的对象,具有不同的 属性 值,除了 someField
值。换句话说,这两种不同类型的对象有一个可能具有相同值的公共字段。
奇怪的是HashSet中没有这个函数。以前没人需要吗?最快的方法是什么?
不知道this could you in your case, it would depends on whether it used hashCode
or equals
internally. Some sources在线有类似问题的是否正在寻找基于equals的解决方案
无论如何,你可以使用find
或first
等内置函数自己实现:
fun <E> HashSet<E>.findByHashCode(other: E): E? = firstOrNull { it.hashCode() == other.hashCode() }
没有标准的解决方案;但是由于 HashMap.get(key)
指定它将参数与存储的键 (key.equals(k)
) 进行比较,而不是相反,你可以通过这个讨厌的 hack 获得预期的结果(讨厌因为它破坏了 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))
此外,如果集合中有多个具有所需哈希码的元素,您将只获得其中一个。
So you are mapping each item with itself as key? Does it mean that associateby{} automatically takes the hashcode() of the element as key
没有。思路是:
说 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")
returns true
,因此用键 "a"
存储的值是 returned,即 "a"
.
or getElement() function automatically checks according to the hashcode of the input element?
它说的是
Return the element from the set equal to element, or null if no such element found.
所以它应该 return "a"
if 它按 HasHash(1).equals("a")
.
的顺序比较它们
假设myHashSet = HashSet<SomeClass>
其中 SomeClass.hashcode() = someField.hashcode()
如何 return 具有指定哈希码的元素,即:
myHashSet.getElementWithHashCode((other as SomeClass).someField.hashcode())
other
和 HashSet
内的对象是不同的对象,具有不同的 属性 值,除了 someField
值。换句话说,这两种不同类型的对象有一个可能具有相同值的公共字段。
奇怪的是HashSet中没有这个函数。以前没人需要吗?最快的方法是什么?
不知道this could you in your case, it would depends on whether it used hashCode
or equals
internally. Some sources在线有类似问题的是否正在寻找基于equals的解决方案
无论如何,你可以使用find
或first
等内置函数自己实现:
fun <E> HashSet<E>.findByHashCode(other: E): E? = firstOrNull { it.hashCode() == other.hashCode() }
没有标准的解决方案;但是由于 HashMap.get(key)
指定它将参数与存储的键 (key.equals(k)
) 进行比较,而不是相反,你可以通过这个讨厌的 hack 获得预期的结果(讨厌因为它破坏了 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))
此外,如果集合中有多个具有所需哈希码的元素,您将只获得其中一个。
So you are mapping each item with itself as key? Does it mean that associateby{} automatically takes the hashcode() of the element as key
没有。思路是:
说
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")
returnstrue
,因此用键"a"
存储的值是 returned,即"a"
.
or getElement() function automatically checks according to the hashcode of the input element?
它说的是
Return the element from the set equal to element, or null if no such element found.
所以它应该 return "a"
if 它按 HasHash(1).equals("a")
.