Классы данных в Котлине
1. обзор
Язык Kotlin представляет концепцию классов данных, которые представляют простые классы, используемые в качестве контейнеров данных, и не содержат никакой дополнительной логики. Проще говоря, решение Kotlin позволяет нам избежать написания большого количества шаблонного кода.
В этой быстрой статье мы рассмотрим классы данных в Kotlin и сравним их с их аналогами в Java.
2. Установка Kotlin
Чтобы приступить к настройке проекта Kotlin, ознакомьтесь с нашим руководствомintroduction to the Kotlin Language.
3. Классы данных в Java
Если бы мы хотели создать записьMovie на Java, нам нужно было бы написать много шаблонного кода:
public class Movie {
private String name;
private String studio;
private float rating;
public Movie(String name, String studio, float rating) {
this.name = name;
this.studio = studio;
this.rating = rating;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getStudio() {
return studio;
}
public void setStudio(String studio) {
this.studio = studio;
}
public float getRating() {
return rating;
}
public void setRating(float rating) {
this.rating = rating;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + Float.floatToIntBits(rating);
result = prime * result + ((studio == null) ? 0 : studio.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Movie other = (Movie) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (Float.floatToIntBits(rating) != Float.floatToIntBits(other.rating))
return false;
if (studio == null) {
if (other.studio != null)
return false;
} else if (!studio.equals(other.studio))
return false;
return true;
}
@Override
public String toString() {
return "Movie [name=" + name + ", studio=" + studio + ", rating=" + rating + "]";
}
}
86 строк кода. Это много, чтобы хранить всего три поля в простом классе.
4. Класс данных Kotlin
Теперь создадимthe same Movie class, with the same functionalities, using Kotlin:
data class Movie(var name: String, var studio: String, var rating: Float)
Как видим, это намного проще и чище. Конструктор,toString(), equals(), hashCode(), и дополнительные функцииcopy() иcomponentN() генерируются автоматически.
4.1. использование
Класс данных создается так же, как и другие классы:
val movie = Movie("Whiplash", "Sony Pictures", 8.5F)
Теперь доступны свойства и функции:
println(movie.name) //Whiplash
println(movie.studio) //Sony Pictures
println(movie.rating) //8.5
movie.rating = 9F
println(movie.toString()) //Movie(name=Whiplash, studio=Sony Pictures, rating=9.0)
4.2. Функция копирования
Функцияcopy() создается на тот случай, если нам нужно скопировать объект, изменив некоторые его свойства, но оставив остальные без изменений.
val betterRating = movie.copy(rating = 9.5F)
println(betterRating.toString()) // Movie(name=Whiplash, studio=Sony Pictures, rating=9.5)
Java не предоставляет четкого, естественного способа копирования / клонирования объектов. Мы могли бы использовать интерфейсClonable,SerializationUtils.clone() илиcloning constructor.
4.3. Заявления о разрушении
Декларации разрушения позволяют нам рассматривать свойства объектов как отдельные значения. Для каждого свойства в классе данных out создаетсяcomponentN():
movie.component1() // name
movie.component2() // studio
movie.component3() // rating
Мы также можем создать несколько переменных из объекта или непосредственно из функции - важно помнить об использовании скобок:
val(name, studio, rating) = movie
fun getMovieInfo() = movie
val(namef, studiof, ratingf) = getMovieInfo()
4.4. Требования к классу данных
Чтобы создать класс данных, мы должны выполнить следующие требования:
-
Первичный конструктор должен иметь хотя бы один параметр
-
Все параметры первичного конструктора должны быть помечены какval илиvar.
-
Классы данных не могут быть абстрактными, открытыми, запечатанными или внутренними
-
(до 1.1.) Классы данных могут реализовывать только интерфейсы
Начиная с версии 1.1, классы данных могут расширять другие классы.
Если сгенерированный класс должен иметь конструктор без параметров, необходимо указать значения по умолчанию для всех свойств:
data class Movie(var name: String = "", var studio: String = "", var rating: Float = 0F)
5. Заключение
Мы видели классы данных в Kotlin, их использование и требования, уменьшенное количество написанного шаблонного кода и сравнения с тем же кодом на Java.
Если вы хотите узнать больше о Kotlin, просмотрите такие статьи, какKotlin Java Interoperability и уже упомянутыйIntroduction to the Kotlin Language.
Полную реализацию этих примеров можно найти в нашемGitHub project.