Там нет стандартного решения; но поскольку 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
}
Но даже тогда HashSet
на JVM не раскрывает нужных вам деталей (например, getElement
в 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 {} автоматически принимает хеш-код () элемента в качестве ключа
Нет. Идея такова:
Say 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 () автоматически проверяет в соответствии с хэш-код элемента ввода?
Что он говорит:
Возвращает элемент из набора, равного элементу, или ноль, если такой элемент не найден.
, поэтому он должен вернуть "a"
, если , он сравнивает их в порядке HasHash(1).equals("a")
.