Kotlin 数据类

在本教程中,我们将看看Kotlin Data Class. 如果您没有阅读 Kotlin Classes的帖子,我们建议您在继续之前这样做。

Kotlin 数据类

Kotlin Data Class Do you get tired of writing thousands of lines of code for your POJO data classes in Java? Every Java Programmer at some stage must have taken a note of the number of lines of code they need to write for classes that just need to store some data. Let's see how a Book.java POJO class looks like:

 1public class Book {
 2
 3    private String name;
 4    private String authorName;
 5    private long lastModifiedTimeStamp;
 6    private float rating;
 7    private int downloads;
 8
 9    public Book(String name, String authorName, long lastModified, float rating, int downloads) {
10        this.name = name;
11        this.authorName = authorName;
12        this.lastModifiedTimeStamp = lastModified;
13        this.rating = rating;
14        this.downloads = downloads;
15    }
16
17    public String getName() {
18        return name;
19    }
20
21    public void setName(String name) {
22        this.name = name;
23    }
24
25    public String getAuthorName() {
26        return authorName;
27    }
28
29    public void setAuthorName(String authorName) {
30        this.authorName = authorName;
31    }
32
33    public long getLastModifiedTimeStamp() {
34        return lastModifiedTimeStamp;
35    }
36
37    public void setLastModifiedTimeStamp(long lastModifiedTimeStamp) {
38        this.lastModifiedTimeStamp = lastModifiedTimeStamp;
39    }
40
41    public float getRating() {
42        return rating;
43    }
44
45    public void setRating(float rating) {
46        this.rating = rating;
47    }
48
49    public int getDownloads() {
50        return downloads;
51    }
52
53    public void setDownloads(int downloads) {
54        this.downloads = downloads;
55    }
56
57    @Override
58    public boolean equals(Object o) {
59        if (this == o) return true;
60        if (o == null || getClass() != o.getClass()) return false;
61
62        Book that = (Book) o;
63
64        if (downloads != that.downloads)
65            return false;
66        if (name != null ? !name.equals(that.name) :
67                that.name != null) {
68            return false;
69        }
70        return authorName != null ?
71                authorName.equals(that.authorName) :
72                that.authorName == null;
73
74    }
75
76    @Override
77    public int hashCode() {
78        int result = name != null ? name.hashCode() : 0;
79        result = 31 * result + (authorName != null ?
80                authorName.hashCode() : 0);
81        result = 31 * result + downloads;
82        return result;
83    }
84
85    @Override
86    public String toString() {
87        return "Book{" +
88                "name='" + name + '\'' +
89                ", author='" + authorName + '\'' +
90                ", lastModifiedTimestamp='" + lastModifiedTimeStamp + '\'' +
91                ", rating='" + rating + '\'' +
92                ", downloads=" + downloads +
93                '}';
94    }
95}

WOAH! 那是96行代码,只需在一个对象中存储5个字段。 除了有 getter setters、toString()、equals() 和hashCode() 方法之外,我们在这里没有做太多。 使用我们的实践中清洁的架构和代码分离的做法,我们需要创建POJO类,因为每个项目都需要存储数据。 这可以增加锅炉板代码。 这是Kotlin用数据类来拯救的地方。 数据类是Kotlin减少锅炉板代码的答案。 上面的 POJO类可以用Kotlin来写下:

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

Kotlin将96行Java代码转换为单行代码。**这是Kotlin在您的项目中减少锅炉板代码的方式!

创建 Kotlin 数据类

以下是创建 Kotlin 数据类的要求。

  • 您需要附加关键字为数据
  • 主要构建器必须至少具有一个参数
  • 主要构建器的每个参数必须具有valvar分配。

Kotlin 数据类内置方法

Kotlin 数据类自动为您创建以下函数。

  • equals()hashCode()
  • toString() 形式 "Book(name=JournalDev, authorName=Anupam)"
  • componentN() 函数为每个参数在指定顺序。这被称为破坏声明
  • copy()

Kotlin 数据类特性

以下是数据类提供的一些功能。

  • 要创建一个无参数构造器,请为主要构造器中存在的每个参数指定默认值
  • 数据类允许分类(不需要提到关键词 open)。
  • 您可以为函数 equals() hashCode()String() 提供明确的实现
  • 对于 copy()componentN() 函数不允许明确的实现
  • 我们可以通过指定构造器中的可见性修改器来控制输出器和设置器的可见性(如下所示)。

数据类中的默认和命名参数

以下是我们的数据类:

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

任何参数都没有默认值集,因此我们需要在实例中为每个参数设置一个参数,如下所示。

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

让我们设置几个默认参数,看看实例化如何改变。

 1data class Book(var name: String, var authorName: String = "Anupam", var lastModified: Long = 1234567, var rating: Float = 5f, var downloads: Int = 1000)
 2fun main(args: Array<String>) {
 3var book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)
 4
 5    book = Book("Kotlin")
 6    book = Book("Swift",downloads = 500)
 7    book = Book("Java","Pankaj",rating = 5f, downloads = 1000)
 8    book = Book("Python","Shubham",rating = 5f)
 9
10}

而不是设置每个参数,我们只能设置非默认参数和我们想要的参数使用 命名参数. 使用命名参数,我们可以将第五参数设置为第二参数,明确指定参数名称,然后是 =

Kotlin 数据类 toString() 方法

toString() 被暗示地创建,并按下面的示例打印参数名和标签。

 1data class Book(var name: String, var authorName: String = "Anupam", var lastModified: Long = 1234567, var rating: Float = 5f, var downloads: Int = 1000)
 2
 3fun main(args: Array<String>) {
 4
 5    var book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)
 6    println(book)
 7    book = Book("Kotlin")
 8    println(book)
 9    book = Book("Swift",downloads = 500)
10    println(book)
11    book = Book("Java","Pankaj",rating = 5f, downloads = 1000)
12    println(book.toString())
13    book = Book("Python","Shubham",rating = 5f)
14    println(book.toString())
15
16}
17
18//Following is printed in the console.
19//Book(name=Android tutorials, authorName=Anupam, lastModified=1234567, rating=4.5, downloads=1000)
20//Book(name=Kotlin, authorName=Anupam, lastModified=1234567, rating=5.0, downloads=1000)
21//Book(name=Swift, authorName=Anupam, lastModified=1234567, rating=5.0, downloads=500)
22//Book(name=Java, authorName=Pankaj, lastModified=1234567, rating=5.0, downloads=1000)
23//Book(name=Python, authorName=Shubham, lastModified=1234567, rating=5.0, downloads=1000)

** 注意**:打印函数默认地添加一个 toString()。

Kotlin 数据类复制() 方法

Copy 函数用于创建数据类的实例副本,其属性变更少数。建议在数据类构建器中使用 val 参数,以便使用实例的不可变属性。

 1data class Book(val name: String, val authorName: String = "Anupam", val lastModified: Long = 1234567, val rating: Float = 5f, val downloads: Int = 1000)
 2
 3fun main(args: Array<String>) {
 4
 5    val book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)
 6    println(book)
 7
 8    val newBook = book.copy(name = "Kotlin")
 9    println(newBook)
10}
11//Following is printed in the console.
12//Book(name=Android tutorials, authorName=Anupam, lastModified=1234567, rating=4.5, downloads=1000)
13//Book(name=Kotlin, authorName=Anupam, lastModified=1234567, rating=4.5, downloads=1000)

Kotlin 数据类等于() 和 hashCode()

hashCode()方法返回对象的哈希代码. 如果两个对象是平等的,则hashCode()产生相同的整数结果.因此,如果hashCode()是平等的,则返回equals(),否则返回false

 1data class Book(val name: String, val authorName: String = "Anupam", val lastModified: Long = 1234567, val rating: Float = 5f, val downloads: Int = 1000)
 2
 3fun main(args: Array<String>) {
 4
 5    val book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)
 6    println("Hashcode is ${book.hashCode()}")
 7
 8    val newBook = book.copy(name = "Kotlin")
 9    println("Hashcode is ${newBook.hashCode()}")
10
11    val copyBook = book.copy()
12    println("Hashcode is ${copyBook.hashCode()}")
13
14    if(copyBook.equals(book))
15        println("copyBook and book are equal")
16
17    if(!book.equals(newBook))
18        println("newBook and book are NOT equal")
19
20}
21
22//Following is printed in the console.
23//Hashcode is 649213087
24//Hashcode is 1237165820
25//Hashcode is 649213087
26//copyBook and book are equal
27//newBook and book are NOT equal

第一个和第三个对象的哈希代码是平等的,因此它们是平等的。 ** 注:在 kotlin 中, equals() 方法相当于 ==。

破坏性声明

componentN() function lets us access each of the arguments specified in the constructor, in the order specified. N is the number of parameters in the constructor. kotlin data classes component functions

 1data class Book(val name: String, val authorName: String = "Anupam", val lastModified: Long = 1234567, val rating: Float = 5f, val downloads: Int = 1000)
 2
 3fun main(args: Array<String>) {
 4
 5    val book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)
 6
 7    println(book.component1()) //Android tutorials
 8    println(book.component2()) //Anupam
 9    println(book.component3()) //1234567
10    println(book.component4()) //4.5
11    println(book.component5()) //1000
12
13}

破构声明允许我们以类对象的属性访问参数,如下所示。

1data class Book(val name: String, val authorName: String = "Anupam", val lastModified: Long = 1234567, val rating: Float = 5f, val downloads: Int = 1000)
2
3fun main(args: Array<String>) {
4
5    val book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)
6    val (n,a,date,rating,downloads) = book
7}

** 注意**:如果对任何参数设置了隐私等可见性修改器,则在上面的函数中无法访问它。

1data class Book(val name: String,private val authorName: String = "Anupam", val lastModified: Long = 1234567, val rating: Float = 5f, val downloads: Int = 1000)
2
3fun main(args: Array<String>) {
4
5    val book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)
6    val (n,a,date,rating,downloads) = book //This won't compile since authorName is private
7}

这是关于Kotlin数据类的快速整合的一切。参考: Kotlin文档

Published At
Categories with 技术
Tagged with
comments powered by Disqus