使用密封类时MutableSet不会防止重复的内容

时间:2019-08-12 20:17:34

标签: kotlin

如果我将MutableSetsealed class一起使用,则MutableSet会接受所有重复的内容。

示例:

sealed class LoginSavedCommand {
    class Login(val email: String, val password: String) : LoginSavedCommand()
    class SaveData(val email: String, val password: String) : LoginSavedCommand()
}

fun main(args: Array<String>) {

    val mSet: MutableSet<LoginSavedCommand> = hashSetOf()

    mSet.add(LoginSavedCommand.Login("oba", "pass"))
    mSet.add(LoginSavedCommand.Login("faiii", "blabla"))

    if (mSet.add(LoginSavedCommand.Login("oba", "pass"))) {
        println("don't")
    } else {
        println("do")
    }
}

我将相同的值传递给LoginSavedCommand.Login,但是MutableSet继续接受添加相同的值(在示例println上打印“不”,我需要打印“ ”,因为我需要使用此selaed class

来防止重复的内容

1 个答案:

答案 0 :(得分:4)

MutableSet通过使用元素的equals checks以及是否使用hashCode来检查它是否包含元素。例如,HashSet使用hashCode来存储并快速查找哈希表中的元素。

示例中sealed class的两个子类不会覆盖equals函数,因此提供了默认的相等性检查实现,即身份相等性(即,一个对象仅等于其自身,并且不同的对象即使属性相等也永远不会相等。

要在LoginSavedCommand中实现MutableSet个项目的唯一性,您需要确保子类提供适当的相等性检查实现。


一种简单的方法是make both subclasses data classes,以便编译器根据以下属性生成equalshashCode实现:

sealed class LoginSavedCommand {
    data class Login(val email: String, val password: String) : LoginSavedCommand()
    data class SaveData(val email: String, val password: String) : LoginSavedCommand()
}

(runnable sample)


或者,在子类中手动覆盖equalshashCode函数。

重要提示::覆盖这些功能时,请确保实现遵循equalshashCode的API参考中描述的功能约定。

例如:

sealed class LoginSavedCommand {
    class Login(val email: String, val password: String) : LoginSavedCommand() {
        override fun equals(other: Any?): Boolean {
            if (this === other) return true
            if (javaClass != other?.javaClass) return false

            other as Login

            if (email != other.email) return false
            if (password != other.password) return false

            return true
        }

        override fun hashCode(): Int {
            var result = email.hashCode()
            result = 31 * result + password.hashCode()
            return result
        }
    }


    class SaveData(val email: String, val password: String) : LoginSavedCommand() {
        /* ... */
    }
}

这些实现是由IntelliJ IDEA使用类主体中的Generate...equals() and hashCode()操作生成的。