我有一个声明如下的变量:
val done = HashSet<StudentProgrammeState>()
在处理结束时,检查如下:
if (done.distinctBy { it.hashCode() }.size < done.size ) {
println("Duplicate states were evaluated.")
}
此消息每次运行都会出现。由于done
是HashSet
,它怎么能包含HashCode
不能区分的多个项目?
以下是StudentProgrammeState
的相等方法:
class StudentProgrammeState(val program: Program) {
val instances = HashSet<StudentModuleInstance>()
override fun equals(other: Any?): Boolean {
if (!(other is StudentProgrammeState)) return false
return (other.program == program) &&
(other.instances.containsAll(instances) &&
instances.containsAll(other.instances))
}
override fun hashCode() = Objects.hash(program, instances)
Equals
不会直接检查hashCode
中的instances
,但该测试应对应于无序集合相等性。
对于StudentModuleInstance:
typealias StudentModuleInstance = Pair<Module, Int>
由于Pair<>
是内置data class
,因此应该具有Kotlin生成的equals
和hashcode
方法。
对于所有正在考虑的实例,program
的值都设置为相同。
答案 0 :(得分:6)
HashSet.add()提供了此合同:
将指定的元素添加到该集中(如果尚不存在)。 更正式地说,将指定元素e添加到该集合中 不包含元素e2使得(e == null?e2 == null:e.equals(e2))。 如果此集合已经包含该元素,则调用将离开该集合 不变并返回false。
尤其没有提到hashCode
。 hashCode的唯一性与add方法无关:具有相同哈希码 的多个项目将进入哈希集。
具有相同hashCode但不等于的项目将最终出现在同一存储桶中,这会降低这些项目的get()
性能。但是除此之外,hashCode并不重要。