Classe de données Kotlin

Dans ce tutoriel, nous allons examiner la classe de données Kotlin. Si vous n’avez pas lu l’article sur les Classes Kotlin, nous vous recommandons de le faire avant de continuer.

Classe de données Kotlin

En avez-vous assez d’écrire des milliers de lignes de code pour vos classes de données POJO en Java ? À un moment donné, chaque programmeur Java doit avoir pris note du nombre de lignes de code qu’il doit écrire pour des classes qui ne font que stocker des données. Voyons à quoi ressemble une classe POJO Book.java :

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 +
                '}';
    }
}

WOAH ! Cela représente 96 lignes de code pour simplement stocker 5 champs dans un objet. Nous ne faisons pas grand-chose ici, à part avoir des méthodes getter setters, toString(), equals() et hashCode(). Avec les architectures propres et la séparation des pratiques de code dans nos pratiques, nous devons créer des classes POJO car chaque projet doit stocker des données quelque part. Cela peut augmenter le code boilerplate. C’est là que Kotlin intervient, avec l’utilisation des classes de données. Les classes de données sont la réponse de Kotlin pour réduire le code boilerplate. La classe POJO ci-dessus peut être écrite en Kotlin de la manière suivante :

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

ET C’EST TOUT. Kotlin convertit un code Java de 96 lignes en une seule ligne de code. C’est ainsi que Kotlin réduit le code boilerplate dans votre projet !

Création de la classe de données Kotlin

Voici les exigences pour créer une classe de données Kotlin.

  • Vous devez ajouter le mot-clé data à la classe
  • Le constructeur principal doit avoir au moins un paramètre
  • Chaque paramètre du constructeur principal doit avoir un val ou un var attribué. Ce n’est pas le cas avec une classe normale, où spécifier un val ou un var n’est pas obligatoire
  • Les classes de données ne peuvent pas être suivies de abstract, open, sealed ou inner

Méthodes intégrées de la classe de données Kotlin

La classe de données Kotlin crée automatiquement les fonctions suivantes pour vous

  • equals() et hashCode()
  • toString() sous la forme "Livre(nom=JournalDev, nomAuteur=Anupam)"
  • Fonctions componentN() pour chacun des paramètres dans l’ordre spécifié. Cela est connu sous le nom de déclarations de désagrégation
  • copy()

Fonctionnalités des classes de données Kotlin

Voici quelques fonctionnalités fournies par une classe de données.

  • Pour créer un constructeur sans paramètre, spécifiez des valeurs par défaut pour chacun des paramètres présents dans le constructeur principal.

  • Une classe de données permet l’héritage (Pas besoin de mentionner le mot-clé open).

  • Vous pouvez fournir des implémentations explicites pour les fonctions equals(), hashCode() et toString().

  • Les implémentations explicites des fonctions copy() et componentN() ne sont pas autorisées.

  • Nous pouvons contrôler la visibilité des accesseurs et mutateurs en spécifiant les modificateurs de visibilité dans le constructeur comme illustré ci-dessous.

    data class Livre(var nom: String, private var nomAuteur: String, var derniereModification: Long, var notation: Float, var téléchargements: Int)
    
  • Un paramètre « val » n’aura pas de mutateur défini implicitement (et ne peut pas être fait explicitement non plus !).

Arguments par Défaut et Nommés dans une Classe de Données

Voici notre classe de données :

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

Aucun des paramètres n’a de valeur par défaut définie. Nous devons donc définir un argument pour chacun d’eux lors de l’instanciation, comme indiqué ci-dessous.

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

Essayons de définir quelques arguments par défaut et voyons comment cela affecte l’instanciation.


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)

}

Au lieu de définir chaque argument, nous pouvons définir uniquement ceux qui ne sont pas par défaut et ceux que nous souhaitons en utilisant l’argument nommé. En utilisant les arguments nommés, nous pouvons définir le 5ème argument comme le deuxième en spécifiant explicitement le nom du paramètre suivi de =. La vie est tellement plus facile de cette manière !

Méthode toString() de la Classe de Données Kotlin

La méthode toString() est créée implicitement et affiche les noms et les étiquettes des arguments pour l’instance, comme illustré ci-dessous.

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) {

    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())


}

//Suivant est imprimé dans la console.
//Livre(nom=Tutoriels Android, nomAuteur=Anupam, derniereModification=1234567, note=4.5, téléchargements=1000)
//Livre(nom=Kotlin, nomAuteur=Anupam, derniereModification=1234567, note=5.0, téléchargements=1000)
//Livre(nom=Swift, nomAuteur=Anupam, derniereModification=1234567, note=5.0, téléchargements=500)
//Livre(nom=Java, nomAuteur=Pankaj, derniereModification=1234567, note=5.0, téléchargements=1000)
//Livre(nom=Python, nomAuteur=Shubham, derniereModification=1234567, note=5.0, téléchargements=1000)

Note: La fonction print ajoute implicitement un toString().

Méthode copy() de la classe de données Kotlin

La fonction copy() est utilisée pour créer une copie d’une instance de la classe de données avec quelques propriétés modifiées. Il est recommandé d’utiliser des paramètres val dans le constructeur des classes de données afin d’utiliser des propriétés immuables des instances. Les objets immuables sont plus faciles à utiliser dans les applications multi-thread. Ainsi, pour créer une copie d’un objet immuable en ne changeant que quelques-unes des propriétés, la fonction copy() est pratique.

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) {

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

    val newBook = book.copy(name = "Kotlin")
    println(newBook)
}
//Suivant est imprimé dans la console.
//Livre(nom=Tutoriels Android, nomAuteur=Anupam, derniereModification=1234567, note=4.5, téléchargements=1000)
//Livre(nom=Kotlin, nomAuteur=Anupam, derniereModification=1234567, note=4.5, téléchargements=1000)

Égalité et hashCode() de la classe de données Kotlin

La méthode hashCode() renvoie le code de hachage de l’objet. Si deux objets sont égaux, hashCode() produit le même résultat entier. Par conséquent, equals() renvoie true si le hashCode() est égal, sinon elle renvoie faux.

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) {

    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")

}

//Ce qui suit est imprimé dans la console.
//Le code de hachage est 649213087
//Le code de hachage est 1237165820
//Le code de hachage est 649213087
//copyBook et book sont égaux
//newBook et book NE sont PAS égaux

Les codes de hachage du premier et du troisième objet sont égaux, donc ils sont égaux. Note : La méthode equals() est équivalente à == en kotlin.

Déclarations de désagrégation

La fonction componentN() nous permet d’accéder à chacun des arguments spécifiés dans le constructeur, dans l’ordre spécifié. N est le nombre de paramètres dans le constructeur.

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
    
}

Les déclarations de désagrégation nous permettent d’accéder aux arguments en tant que propriétés de l’objet de la classe comme indiqué ci-dessous.

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
}

Remarque: Si un modificateur de visibilité tel que « private » est défini sur l’un des arguments, il ne peut pas être accédé dans la fonction ci-dessus.

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
}

C’est tout pour un bref survol sur les classes de données Kotlin. Références: Documentation Kotlin

Source:
https://www.digitalocean.com/community/tutorials/kotlin-data-class