Kotlin равен и генератор хеш-кода - PullRequest
0 голосов
/ 21 мая 2018

Мне известно, что в классах Kotlin классы равенства и хэш-кода будут создаваться автоматически следующим образом:

data class CSVColumn(private val index: Int, val value: String) {
}

Мой вопрос заключается в том, можно ли в реализации использовать только одно из этих свойств (например,как index) без написания кода самостоятельно.То, что раньше было очень лаконичным классом, теперь выглядит так:

data class CSVColumn(private val index: Int, val value: String) {

    override fun equals(other: Any?): Boolean {
        if (this === other) {
            return true
        }
        if (javaClass != other?.javaClass) {
            return false
        }
        other as CSVColumn
        if (index != other.index) {
            return false
        }
        return true
    }

    override fun hashCode(): Int {
        return index
    }

}

В Java с Lombok я могу сделать что-то вроде:

@Value
@EqualsAndHasCode(of="index")
public class CsvColumn {
    private final int index;
    private final String value;
}

Было бы круто, если бы был способскажи Котлину нечто подобное.

Ответы [ 5 ]

0 голосов
/ 31 июля 2019

Я полагаю, что сейчас нам нужно написать equals () / hashCode () вручную.https://discuss.kotlinlang.org/t/automatically-generate-equals-hashcode-methods/3779

Это не поддерживается и планируется, ИМХО.

Ниже приведены некоторые полезные ссылки.

https://discuss.kotlinlang.org/t/how-does-kotlin-implement-equals-and-hashcode/940 https://kotlinlang.org/docs/reference/data-classes.html https://medium.com/@appmattus/effective-kotlin-item-11-always-override-hashcode-when-you-override-equals-608a090aeaed

0 голосов
/ 31 июля 2019

Полагаю, сейчас нам нужно написать equals()/hashCode() вручную.https://discuss.kotlinlang.org/t/automatically-generate-equals-hashcode-methods/3779

Не поддерживается и планируется, ИМХО.

0 голосов
/ 21 мая 2018

Вы не можете сделать что-то подобное для классов данных, они всегда генерируют equals и hashCode одинаково, нет способа предоставить им такие подсказки или опции.

Однако они тольковключить свойства, которые находятся в первичном конструкторе, так что вы можете сделать это, чтобы они включали только index:

data class CSVColumn(private val index: Int, value: String) {
    val value: String = value
}

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

Таким образом, вам придется каким-то образом ввести вторичный конструктор, который принимает два параметра, например:

class CSVColumn private constructor(private val index: Int) {

    var value: String = ""

    constructor(index: Int, value: String) : this(index) {
        this.value = value
    }

}

... но теперь ваш *Свойство 1014 * должно быть var, чтобы вторичный конструктор мог установить его значение.

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


Редактировать: as @Тайнн отметил, что частный сеттер может быть решением, так что ваш value не может изменяться вне класса:

class CSVColumn private constructor(private val index: Int) {

    var value: String = ""
        private set

    constructor(index: Int, value: String) : this(index) {
        this.value = value
    }

}
0 голосов
/ 08 мая 2019

Я написал небольшую утилиту под названием "stem", которая позволяет вам выбирать, какие свойства учитывать для равенства и хеширования.Результирующий код настолько мал, насколько это возможно для ручной equals()/hashCode() реализации:

class CSVColumn(private val index: Int, val value: String)  {
    private val stem = Stem(this, { index })

    override fun equals(other: Any?) = stem.eq(other)
    override fun hashCode() = stem.hc()
}

Вы можете увидеть его реализацию здесь .

0 голосов
/ 21 мая 2018

Из документации Классы данных вы получаете:

Обратите внимание, что компилятор использует только свойства, определенные внутри основного конструктора, для автоматически сгенерированных функций.Чтобы исключить свойство из сгенерированных реализаций, объявите его внутри тела класса

Так что вам нужно реализовать equals() и hashCode() вручную или с помощью Kotlin Compiler Plugin .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...