Рубрики
Без рубрики

Классы данных в Kotlin

(Сегодня безумно напряженный день, такая простая статья, чтобы выполнить мою норму. Извини) Я уже упоминал о Kotlin be… Помечено 100daysofcode, kotlin, java.

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

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

Классы данных – это просто классы. С этой точки зрения в них нет ничего особенного. Фактическое ключевое слово “data” изначально было не более чем аннотацией, которую компилятор увидел и на которую отреагировал. (Я, честно говоря, не уверен, что это все еще так, я боюсь). Как таковые, они могут делать (почти) все, что может делать обычный класс.

Суть классов данных в том, что – хотите верьте, хотите нет – они предназначены для представления данных, а не функциональности. Это определение Java-компонента из Java-land. И это именно то, чем они являются. Только значительно больше линий потока. Когда вы добавляете ключевое слово “data” (или аннотацию, или что бы это ни было) перед определением класса, то, что вы говорите компилятору, это:

  • Создать класс
  • С этим набором полей
  • С получателями (и, возможно, установщиками) для каждого поля
  • С помощью равно и Хэш-код метод, который является правильным
  • С помощью правильного метода toString
  • С помощью метода copy
  • С набором компонентов методы

Первые три из них в любом случае являются лишь частью того, как Kotlin определяет классы. В этом нет ничего особенного. Это остальные 4, в которых действительно участвуют классы данных.

Написание равно , Хэш-код и toString методы – это несложно. Написать их правильно все же можно. Но даже в этом случае большую часть времени люди либо заставляют свою среду разработки генерировать их автоматически, либо используют что-то вроде классов Commons-Lang Equals/hashCode/ToStringBuilder. И это прекрасно, но не без затрат. Сгенерированные из IDE будут устаревать, как только класс изменится, если вы не забудете обновлять их. Классы Builder либо столкнутся с теми же проблемами, либо будут использовать отражение с соответствующими затратами на производительность.

Окончательный набор методов – это просто несколько вспомогательных методов. Метод copy позволяет вам взять один объект и создать новый с теми же значениями. Или с некоторыми теми же значениями. Вы можете выборочно выбирать и выбирать, какие значения вы хотите заменить новыми. Например:

val user = User(username = "graham", email = "my.email@example.com", banned = false)
val copiedUser = user.copy(email = "my.real.email@example.com)

В этом случае скопированный пользователь имеет:

  • имя пользователя
  • электронная почта = ” my.real.email@example.com “
  • запрещенный

И вам нужно было указать только одно из этих значений.

Методы component используются при деструктурировании, что само по себе является темой. Проще говоря, это позволяет вам взять класс и разложить его на отдельные поля. Это очень полезно в нескольких местах – например, при сопоставлении с образцом – когда вас интересует не сам класс, а только отдельные поля.

Короче говоря, классы данных не представляют собой ничего особенного. Они на самом деле не делай что угодно. Они просто позволяют вам не писать много шаблонов для того, что по сути является сгенерированными методами. Вы можете написать JavaBean с несколькими полями и получить все правильные методы JavaBean для всего, что вам нужно, и еще несколько сверху, в одной строке кода. Чтобы украсть пример из Reddit, он превращает это:

public class User {
    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public String component1() {
        return name;
    }

    public int component2() {
        return age;
    }

    public User copy() {
        return new User(name, age);
    }

    public User copy(String newName) {
        return new User(newName, age);
    }

    public User copy(String newName, int newAge) {
        return new User(newName, newAge);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        User user = (User) o;

        if (age != user.age) return false;
        return name != null ? name.equals(user.name) : user.name == null;
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        return result;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

в это:

data class User(val name: String, val age: Int)

Оригинал: “https://dev.to/grahamcox82/data-classes-in-kotlin”