Поиск по сайту:

Класс данных Котлина


В этом уроке мы рассмотрим Kotlin Data Class. Если вы не читали пост о классах Kotlin, мы рекомендуем вам сделать это, прежде чем продолжить.

Класс данных Котлина

public class Book {

    private String name;
    private String authorName;
    private long lastModifiedTimeStamp;
    private float rating;
    private int downloads;


    public Book(String name, String authorName, long lastModified, float rating, int downloads) {
        this.name = name;
        this.authorName = authorName;
        this.lastModifiedTimeStamp = lastModified;
        this.rating = rating;
        this.downloads = downloads;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthorName() {
        return authorName;
    }

    public void setAuthorName(String authorName) {
        this.authorName = authorName;
    }

    public long getLastModifiedTimeStamp() {
        return lastModifiedTimeStamp;
    }

    public void setLastModifiedTimeStamp(long lastModifiedTimeStamp) {
        this.lastModifiedTimeStamp = lastModifiedTimeStamp;
    }

    public float getRating() {
        return rating;
    }

    public void setRating(float rating) {
        this.rating = rating;
    }

    public int getDownloads() {
        return downloads;
    }

    public void setDownloads(int downloads) {
        this.downloads = downloads;
    }

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

        Book that = (Book) o;

        if (downloads != that.downloads)
            return false;
        if (name != null ? !name.equals(that.name) :
                that.name != null) {
            return false;
        }
        return authorName != null ?
                authorName.equals(that.authorName) :
                that.authorName == null;

    }

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

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + authorName + '\'' +
                ", lastModifiedTimestamp='" + lastModifiedTimeStamp + '\'' +
                ", rating='" + rating + '\'' +
                ", downloads=" + downloads +
                '}';
    }
}

ВАУ! Это 96 строк кода для хранения 5 полей в объекте. Здесь мы мало что делаем, кроме установки геттеров, методов toString(), equals() и hashCode(). С чистой архитектурой и разделением методов кода в наших практиках нам необходимо создавать классы POJO, поскольку каждый проект должен где-то хранить данные. Это может увеличить стандартный код. Здесь на помощь приходит Kotlin с использованием классов данных. Классы данных — это ответ Kotlin на сокращение шаблонного кода. Приведенный выше класс POJO можно написать на Kotlin следующим образом:

data class Book(var name: String, var authorName: String, var lastModified: Long, var rating: Float, var downloads: Int)

ВОТ И ВСЕ. Kotlin преобразует 96-строчный код Java в одну строку кода. Это способ Kotlin сократить шаблонный код в вашем проекте!

Создание класса данных Kotlin

Ниже приведены требования для создания класса данных Kotlin.

  • Вам необходимо добавить в класс ключевое слово data
  • Первичный конструктор должен иметь хотя бы один параметр.
  • Каждому параметру основного конструктора должен быть назначен val или var. Это не относится к обычному классу, где указание val или var не является обязательным.
  • К классам данных нельзя добавить abstract, open, sealed или inner

Встроенные методы класса данных Kotlin

Класс Kotlin Data автоматически создает для вас следующие функции.

  • equals() и hashCode()
  • toString() вида Book(name=JournalDev, authorName=Anupam)
  • componentN() выполняет функции для каждого из параметров в указанном порядке. Это известно как объявления деструктурирования.
  • копировать()

Функции класса данных Kotlin

Ниже приведены некоторые функции, которые предоставляет класс данных.

  • To create a parameterless constructor, specify default values to each of the parameters present in the primary constructor.

  • A Data Class allows subclassing(No need to mention the keyword open).

  • You can provide explicit implementations for the functions equals() hashCode() and toString()

  • Explicit implementations for copy() and componentN() functions are not allowed.

  • We can control the visibility of the getters and setters by specifying the visibility modifiers in the constructor as shown below.

    data class Book(var name: String,private var authorName: String, var lastModified: Long, var rating: Float, var downloads: Int)
    
  • A val parameter won’t have a setter defined implicitly(can’t be done explicitly too!).

Аргументы по умолчанию и именованные в классе данных

Ниже приведен наш класс данных:

data class Book(var name: String, var authorName: String, var lastModified: Long, var rating: Float, var downloads: Int)

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

fun main(args: Array<String>) {
val book = Book("Android Tutorials","Anupam", 1234567, 4.5f, 1000)
}

Давайте установим несколько аргументов по умолчанию и посмотрим, как изменится инстанцирование.


data class Book(var name: String, var authorName: String = "Anupam", var lastModified: Long = 1234567, var rating: Float = 5f, var downloads: Int = 1000)
fun main(args: Array<String>) {
var book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)

    book = Book("Kotlin")
    book = Book("Swift",downloads = 500)
    book = Book("Java","Pankaj",rating = 5f, downloads = 1000)
    book = Book("Python","Shubham",rating = 5f)

}

Вместо того, чтобы устанавливать каждый аргумент, мы можем установить только те, которые не используются по умолчанию, и те, которые мы хотим, используя именованный аргумент. Используя именованные аргументы, мы можем установить 5-й аргумент в качестве второго, явно указав имя параметра, за которым следует =. Так проще жить!

Метод toString() класса данных Kotlin

ToString() создается неявно и печатает имена аргументов и метки для экземпляра, как показано ниже.

data class Book(var name: String, var authorName: String = "Anupam", var lastModified: Long = 1234567, var rating: Float = 5f, var downloads: Int = 1000)


fun main(args: Array<String>) {

    var book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)
    println(book)
    book = Book("Kotlin")
    println(book)
    book = Book("Swift",downloads = 500)
    println(book)
    book = Book("Java","Pankaj",rating = 5f, downloads = 1000)
    println(book.toString())
    book = Book("Python","Shubham",rating = 5f)
    println(book.toString())


}

//Following is printed in the console.
//Book(name=Android tutorials, authorName=Anupam, lastModified=1234567, rating=4.5, downloads=1000)
//Book(name=Kotlin, authorName=Anupam, lastModified=1234567, rating=5.0, downloads=1000)
//Book(name=Swift, authorName=Anupam, lastModified=1234567, rating=5.0, downloads=500)
//Book(name=Java, authorName=Pankaj, lastModified=1234567, rating=5.0, downloads=1000)
//Book(name=Python, authorName=Shubham, lastModified=1234567, rating=5.0, downloads=1000)

Примечание: функция print неявно добавляет toString().

Метод копирования класса данных Kotlin()

Функция копирования используется для создания копии экземпляра класса данных с некоторыми измененными свойствами. Рекомендуется использовать параметры val в конструкторе классов данных, чтобы использовать неизменяемые свойства экземпляров. Неизменяемые объекты проще при работе с многопоточными приложениями. Следовательно, чтобы создать копию неизменяемого объекта, изменив лишь несколько свойств, удобна функция copy().

data class Book(val name: String, val authorName: String = "Anupam", val lastModified: Long = 1234567, val rating: Float = 5f, val downloads: Int = 1000)

fun main(args: Array<String>) {

    val book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)
    println(book)

    val newBook = book.copy(name = "Kotlin")
    println(newBook)
}
//Following is printed in the console.
//Book(name=Android tutorials, authorName=Anupam, lastModified=1234567, rating=4.5, downloads=1000)
//Book(name=Kotlin, authorName=Anupam, lastModified=1234567, rating=4.5, downloads=1000)

Класс данных Kotlin equals() и hashCode()

Метод hashCode() возвращает хеш-код для объекта. Если два объекта равны, hashCode() возвращает один и тот же целочисленный результат. Следовательно, equals() возвращает true, если hashCode() равен, иначе возвращает false.

data class Book(val name: String, val authorName: String = "Anupam", val lastModified: Long = 1234567, val rating: Float = 5f, val downloads: Int = 1000)

fun main(args: Array<String>) {

    val book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)
    println("Hashcode is ${book.hashCode()}")

    val newBook = book.copy(name = "Kotlin")
    println("Hashcode is ${newBook.hashCode()}")

    val copyBook = book.copy()
    println("Hashcode is ${copyBook.hashCode()}")


    if(copyBook.equals(book))
        println("copyBook and book are equal")

    if(!book.equals(newBook))
        println("newBook and book are NOT equal")

}

//Following is printed in the console.
//Hashcode is 649213087
//Hashcode is 1237165820
//Hashcode is 649213087
//copyBook and book are equal
//newBook and book are NOT equal

Хэш-коды первого и третьего объекта равны, следовательно, они равны. Примечание. Метод equals() эквивалентен == в kotlin.

Разрушение объявлений

data class Book(val name: String, val authorName: String = "Anupam", val lastModified: Long = 1234567, val rating: Float = 5f, val downloads: Int = 1000)

fun main(args: Array<String>) {

    val book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)

    println(book.component1()) //Android tutorials
    println(book.component2()) //Anupam
    println(book.component3()) //1234567
    println(book.component4()) //4.5
    println(book.component5()) //1000
    
}

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

data class Book(val name: String, val authorName: String = "Anupam", val lastModified: Long = 1234567, val rating: Float = 5f, val downloads: Int = 1000)

fun main(args: Array<String>) {

    val book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)
    val (n,a,date,rating,downloads) = book
}

Примечание. Если модификатор видимости, такой как private, установлен для любого из аргументов, к нему нельзя получить доступ в приведенной выше функции.

data class Book(val name: String,private val authorName: String = "Anupam", val lastModified: Long = 1234567, val rating: Float = 5f, val downloads: Int = 1000)

fun main(args: Array<String>) {

    val book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)
    val (n,a,date,rating,downloads) = book //This won't compile since authorName is private
}

Это все, что нужно для быстрого ознакомления с классами данных Kotlin. Ссылки: Kotlin Документы