Как добавить пользователя на карту с помощью dataclass, Котлин

#android-studio #kotlin #data-class

Вопрос:

Поэтому я хочу добавить пользователя на карту, а затем проверить, добавлен ли он туда. например, пользователь вводит свою информацию, я сохраняю свою электронную почту в качестве ключа, а информацию в классе данных в качестве значения

 private val users = mutableMapOf<String, User>()

private fun add(){
    check()
    val email = binding.email.text.toString()
    val firstName = binding.firstname.text.toString()
    val lastName = binding.lastname.text.toString()
    val age = binding.age.text.toString()

    users["default"] = User("email","firstName","lastName","age")
    for (user in users.keys){
        if (email == user) {
            Toast.makeText(this,"not successful",Toast.LENGTH_SHORT).show()
            break
        }else{
            users[email] = User(email,firstName,lastName,age)
            Toast.makeText(this,"successful",Toast.LENGTH_SHORT).show()
        }
    }
}
 

но когда я нажимаю на кнопку при первом запуске, она просто говорит «успешно», но при втором щелчке она должна вернуться не успешно, потому что этот пользователь уже был создан, но он показывает оба тоста.

можете ли вы сказать мне, почему он это делает и как я могу это исправить?

Комментарии:

1. У меня есть совет, который поможет упростить выполнение кода. На вашей карте есть ключи, которые являются адресами электронной почты, поэтому более полезным именем для свойства было usersByEmail бы , и когда вы повторяете ключи, вы не должны называть ключи user , так как это не то, что они есть.

Ответ №1:

это связано с тем фактом, что for цикл не гарантирует, что он будет повторять ключи в том порядке, в котором вы ожидаете.

Например, рассмотрим эту карту:

 users["default"] = User("email","firstName","lastName","age")
users["zzz@xyz.com"] = User("email","zz","z","age")
 

предположим, что ключи будут повторяться в алфавитном порядке(на самом деле это не так в большинстве случаев) и что у вас были email=zzz@xyz.com

На первой итерации user строка будет ссылаться на default . Поскольку email == user значение равно false, оно перейдет в else ветвь вашего цикла. Затем, на следующей итерации, user будет zzz@xyz.com и email == user будет верно; просто дважды отправьте уведомление «тост».

Похоже, вы пытаетесь вставить элемент, если он не существует, или показать ошибку, если она существует. Вместо for цикла рассмотрите возможность проверки наличия предыдущего ключа с containsKey помощью, а затем, при необходимости, добавления нового элемента.

 // In kotlin, you can create a map with initial values by using the "to" infix function
private val users = mutableMapOf<String, User>(
    "default" to User("email","firstName","lastName","age")
)

private fun add() {
    check()
    val email = binding.email.text.toString()
    val firstName = binding.firstname.text.toString()
    val lastName = binding.lastname.text.toString()
    val age = binding.age.text.toString()

    if (users.containsKey(email)) {
        Toast.makeText(this,"not successful",Toast.LENGTH_SHORT).show()
        return
    }

    users[email] = User(email,firstName,lastName,age)
    Toast.makeText(this,"successful",Toast.LENGTH_SHORT).show()
}
 

Ответ №2:

Это связано с тем, что вы сравниваете ключ карты со значением электронной почты. Вам нужно сравнить значение электронного письма. Попробуйте сделать следующее в рамках для: email == user.value.email .

Комментарии:

1. Но они используют значение электронной почты в качестве ключа, так что здесь это уместно.

2. Вы уверены. Я не заметил, что ключом была электронная почта.