資料類是一個簡單的類,用於儲存資料/狀態並包含標準功能(函式)。 data
關鍵字用於將類宣告為資料類。
data class User(val name: String, val age: Int)
宣告資料類必須至少包含一個帶有屬性引數(val
或var
)的主建構函式。
資料類內部有以下函式:
equals(): Boolean
hashCode(): Int
toString(): String
component()
函式對應的屬性copy()
由於資料類內部存在上述函式,因此資料類消除了反復套用程式碼。
*Java資料類和Kotlin資料類的比較
如果想使用資料類在Java中建立使用者資料項,則需要大量反復套用的程式碼。
import java.util.Objects;
public class User {
private String name;
private int id;
private String email;
public User(String name, int id, String email) {
this.name = name;
this.id = id;
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public intgetId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof User)) return false;
User user = (User) o;
return getId() == user.getId() &&
Objects.equals(getName(), user.getName()) &&
Objects.equals(getEmail(), user.getEmail());
}
@Override
public inthashCode() {
return Objects.hash(getName(), getId(), getEmail());
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", id=" + id +
", email='" + email + '\'' +
'}';
}
}
使用User
類的物件,呼叫上述Java資料類別建構函式,如下所示 -
class MyClass{
public static void main(String agrs[]){
User u = new User("Susen",10010,"[email protected]");
System.out.println(u);
}
}
執行上面範例程式碼,得到以下結果 -
User{name='Susen', id=10010, email='[email protected]'}
上述Java資料類程式碼在Kotlin資料程式碼中使用一行重寫完事 -
data class User(var name: String, var id: Int, var email: String)
使用User
類的物件呼叫上述Kotlin資料類別建構函式 -
data class User(var name: String, var id: Int, var email: String)
fun main(agrs: Array<String>) {
val u = User("Maxsu", 10010, "[email protected]")
println(u)
}
執行上面範例程式碼,得到以下結果 -
User{name='Maxsu', id=10010, email='[email protected]'}
要建立資料類,首先需要滿足以下要求:
val
或var
。1.1
版本之前,資料類只實現介面。1.1
版本之後,資料類可以擴充套件其他類。Kotlin資料類僅關注資料而非程式碼實現。
下面來看一個沒有資料類的簡單程式。 在這個類中,嘗試使用物件列印Product
類的參照。
class Product(varitem: String, var price: Int)
fun main(agrs: Array<String>) {
val p = Product("Thinkpad", 5600)
println(p)
}
在列印Product
類的參照時,它會顯示類名為Product
的hashCode()
。它不列印物件屬性的資料。
執行上面範例程式碼,得到以下結果 -
Product@5e2de80c
上述程式使用資料類(data class
)重寫,列印Product
類的參照並顯示物件的資料。上面程式碼中之所以發生這種情況,是因為資料類內部包含toString()
方法,它預設只是顯示物件的字串表示形式。
data class Product(var item: String, var price: Int)
fun main(agrs: Array<String>) {
val p = Product("Thinkpad", 5600)
println(p)
}
執行上面範例程式碼,得到以下結果 -
Product(item=Thinkpad, price=5600)
equal()
方法用於檢查其他物件是否「等於」當前物件。 在兩個或多個hashCode()
之間進行比較時,如果hashCode()
相等,則equals()
方法返回true
,否則返回false
。
例如,讓我們看一個例子,一個普通類比較具有相同資料的Product
類的兩個參照。
class Product(var item: String, var price: Int)
fun main(agrs: Array<String>) {
val p1 = Product("Thinkpad", 5000)
val p2 = Product("Thinkpad", 5000)
println(p1==p2)
println(p1.equals(p2))
}
在上述程式中,參照p1
和參照p2
具有不同的參照。 由於p1
和p2
中的參照值不同,所以進行比較結果為false
。
執行上面範例程式碼,得到以下結果 -
false
false
上述程式使用資料類重寫,列印Product
類的參照並顯示物件的資料。hashCode()
方法返回物件的雜湊碼。 如果兩個物件相等,則hashCode()
會產生相同的整數結果。
data class Product(var item: String, var price: Int)
fun main(agrs: Array<String>) {
val p1 = Product("Thinkpad", 5000)
val p2 = Product("Thinkpad", 5000)
println(p1==p2)
println(p1.equals(p2))
}
執行上面範例程式碼,得到以下結果 -
true
true
資料類提供了一個copy()
方法,用於建立物件的副本(或冒號)。 使用copy()
方法,可以更改物件的部分或全部屬性。
範例:
data class Product(var item: String, var price: Int)
fun main(agrs: Array<String>) {
val p1 = Product("Thinkpad", 5000)
println("p1 包含資料為: $p1")
val p2 = p1.copy()
println("p2 拷貝物件包含p1的預設資料為:: $p2")
val p3 = p1.copy(price = 20000)
println("p3 包含 p1 和修改後的資料為 : $p3")
}
執行上面範例程式碼,得到以下結果 -
p1 包含資料為: Product(item=Thinkpad, price=5000)
p2 拷貝物件包含p1的預設資料為:: Product(item=Thinkpad, price=5000)
p3 包含 p1 和修改後的資料為 : Product(item=Thinkpad, price=20000)
還可以在資料類的主建構函式中分配預設引數。 如果需要,可以稍後在程式中更改這些預設值。
範例:
data class Product(var item: String = "Apple Mac", var price: Int = 15000)
fun main(agrs: Array<String>) {
val p1 = Product(price = 20000)
println(p1)
}
執行上面範例程式碼,得到以下結果 -
Product(item=Apple Mac, price=20000)