在Kotlin中,HashSet包含通过哈希重复的元素

时间:2018-08-15 19:42:42

标签: kotlin set

我有一个声明如下的变量:

val done = HashSet<StudentProgrammeState>()

在处理结束时,检查如下:

if (done.distinctBy { it.hashCode() }.size < done.size ) {
    println("Duplicate states were evaluated.")
}

此消息每次运行都会出现。由于doneHashSet,它怎么能包含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生成的equalshashcode方法。

对于所有正在考虑的实例,program的值都设置为相同。

1 个答案:

答案 0 :(得分:6)

HashSet.add()提供了此合同:

  

将指定的元素添加到该集中(如果尚不存在)。       更正式地说,将指定元素e添加到该集合中       不包含元素e2使​​得(e == null?e2 == null:e.equals(e2))。       如果此集合已经包含该元素,则调用将离开该集合       不变并返回false。

尤其没有提到hashCode。 hashCode的唯一性与add方法无关:具有相同哈希码 的多个项目将进入哈希集。

具有相同hashCode但不等于的项目将最终出现在同一存储桶中,这会降低这些项目的get()性能。但是除此之外,hashCode并不重要。