Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
equals() в Kotlin/Java
Определение
equals() — это метод, который **сравнивает содержимое двух объектов** по смыслу, а не по ссылке в памяти. Переопределяется из базового класса Object.
Зачем нужен?
По умолчанию оператор == сравнивает ссылки на объекты:
val user1 = User("John", 25)
val user2 = User("John", 25)
// По умолчанию
user1 == user2 // false! (разные ссылки в памяти)
user1 === user2 // false! (разные объекты)
Мы хотим сравнивать по содержимому:
user1 == user2 // true! (одинаковые данные)
Реализация в Kotlin
class User(
val name: String,
val age: Int
) {
override fun equals(other: Any?): Boolean {
// Проверка типа
if (this === other) return true
if (other !is User) return false
// Сравнение полей
return name == other.name && age == other.age
}
override fun hashCode(): Int {
return name.hashCode() + age.hashCode()
}
}
val user1 = User("John", 25)
val user2 = User("John", 25)
user1 == user2 // true!
Data class (автоматический equals)
data class User(
val name: String,
val age: Int
)
val user1 = User("John", 25)
val user2 = User("John", 25)
user1 == user2 // true! Автоматически сгенерировано
Когда переопределять equals()?
1. Если объект используется в коллекциях:
class User(val id: Int, val name: String) {
override fun equals(other: Any?) = other is User && id == other.id
override fun hashCode() = id.hashCode()
}
val users = mutableSetOf<User>()
users.add(User(1, "John"))
users.add(User(1, "Jane")) // Не добавится! Уже есть id=1
2. Если нужно сравнивать по смыслу:
data class Point(val x: Int, val y: Int)
val p1 = Point(5, 10)
val p2 = Point(5, 10)
p1 == p2 // true
3. В наследовании:
open class Entity(val id: Int) {
override fun equals(other: Any?): Boolean {
if (other !is Entity) return false
return id == other.id
}
override fun hashCode() = id.hashCode()
}
class User(id: Int, val name: String) : Entity(id)
val user = User(1, "John")
val entity = Entity(1)
user == entity // true! (по id)
Примеры использования
Поиск в списке:
val users = listOf(
User("John", 25),
User("Jane", 30)
)
val john = User("John", 25)
users.contains(john) // true! Использует equals()
Проверка в условии:
if (currentUser == selectedUser) {
println("Один и тот же пользователь")
}
Удаление дубликатов:
val allUsers = listOf(
User("John", 25),
User("John", 25), // Дубликат
User("Jane", 30)
)
allUsers.distinct() // Удалит дубликат, используя equals()
Правило: equals vs hashCode
Важно: если переопределяешь equals(), ВСЕГДА переопредели hashCode()!
// Плохо — без hashCode
class User(val id: Int) {
override fun equals(other: Any?) =
other is User && id == other.id
// hashCode() не переопределён!
}
val set = setOf(User(1), User(1), User(1))
println(set.size) // 3! Ошибка
// Хорошо — с hashCode
class User(val id: Int) {
override fun equals(other: Any?) =
other is User && id == other.id
override fun hashCode() = id.hashCode()
}
val set = setOf(User(1), User(1), User(1))
println(set.size) // 1! Правильно
Контракт equals/hashCode
Если a.equals(b) == true, то a.hashCode() == b.hashCode()
- Это гарантирует правильную работу HashSet, HashMap и др.
- Нарушение контракта = баги в коллекциях
Вывод
equals() нужен для **сравнения содержимого объектов**:
- Используется в коллекциях (List.contains(), Set, Map)
- Переопредели, если объект имеет "смысл" сравнения
- Используй data class для автоматического equals()
- Всегда переопредели hashCode() одновременно
- В Java это критично, в Kotlin часто автоматизировано