Kotlin 学习笔记(二)—— 数据类、枚举类、循环、常用集合及操作符的写法(上)

简介: Kotlin 学习笔记(二)—— 数据类、枚举类、循环、常用集合及操作符的写法(上)

在上篇笔记中,我们对 Kotlin 的基本类型、关键字、类与对象,以及与 Java 之间互调的内容有了一些认识,这篇笔记来看看 Kotlin 中几种特殊的类,以及集合相关的常用操作。


1. Kotlin 数据类


Kotlin 语言中有个特殊的类叫 数据类这个类型是 Kotlin 专门用来表示一个 Java Bean 的,为啥这么说?因为它帮我们自动生成了一个数据类应该有的方法。比如:getter/setter 方法、toString()、hashCode()、equals()、copy() 方法。举个栗子:

// code 1
data class Book(val id: Int, val name: String) {
}


Kotlin 代码就这么点,然后再看看为我们生成的 Java 代码:(如何查看生成的 Java 代码?找到 AndroidStudio 的 Tools 选项,依次选 Kotlin、show Kotlin ByteCode,然后在新出现的代码窗口点击 Decompile 就可以看到生成的 Java 代码了)

// code 2
public final class Book {
   private final int id;
   @NotNull
   private final String name;
   public final int getId() {
      return this.id;
   }
   @NotNull
   public final String getName() {
      return this.name;
   }
   public Book(int id, @NotNull String name) {
      Intrinsics.checkNotNullParameter(name, "name");
      super();
      this.id = id;
      this.name = name;
   }
   public final int component1() {
      return this.id;
   }
   @NotNull
   public final String component2() {
      return this.name;
   }
   @NotNull
   public final Book copy(int id, @NotNull String name) {
      Intrinsics.checkNotNullParameter(name, "name");
      return new Book(id, name);
   }
   // $FF: synthetic method
   public static Book copy$default(Book var0, int var1, String var2, int var3, Object var4) {
      if ((var3 & 1) != 0) {
         var1 = var0.id;
      }
      if ((var3 & 2) != 0) {
         var2 = var0.name;
      }
      return var0.copy(var1, var2);
   }
   @NotNull
   public String toString() {
      return "Book(id=" + this.id + ", name=" + this.name + ")";
   }
   public int hashCode() {
      int var10000 = this.id * 31;
      String var10001 = this.name;
      return var10000 + (var10001 != null ? var10001.hashCode() : 0);
   }
   public boolean equals(@Nullable Object var1) {
      if (this != var1) {
         if (var1 instanceof Book) {
            Book var2 = (Book)var1;
            if (this.id == var2.id && Intrinsics.areEqual(this.name, var2.name)) {
               return true;
            }
         }
         return false;
      } else {
         return true;
      }
   }
}

想不到吧?一行 Kotlin 竟然帮我们干了这么多事!这也说明用 Kotlin 确实能减少代码量,提升 Coding 效率。再看看 Kotlin 数据类的特点。

首先,data class 是一个 final 类,说明 data class 是无法被继承的,哪怕在它前面加 open 关键字也不行。细心的同学可能发现了:这个 Book 并没有 setter 方法呀?没错,那是因为之前在写 Kotlin 代码时,把 id 和 name 两个参数设置为 val 不可变变量了,如果改成 var 再次生成一下,你就会发现有 setter 方法了。

然后,其他的 hashCode、toString、equals、copy 方法都是常规的一些操作,当然,也可以在 data class 里面重写这些方法,达到自己想要的效果。

再看一眼,发现还有两个比较陌生的方法:component1() 和 component2(),和 getter 方法一样啊,为啥?其实这两个方法是 data class 用来解构的,方便用户直接拿到某个对象中的属性值,如下:

// code 3
val book = Book(1, "鲁迅文集")
book.id = 23    // setter 方法
val(bookId, bookName) = book    // 对 book 直接解构
print("bookName = $bookName")    // 输出:“bookName = 鲁迅文集”


如果还有第三个属性的话一样的,就会给你生成 component3(),以此类推。这两个 component 是 data class 自动生成的,如果普通的 class 也想这样解构,也可以,需要使用 operator 关键字,对类中的属性做一个关联:

// code 4
class Car(var brand: String, var price: Double) {    // 普通类 解构
    operator fun component1(): String {
        return this.brand
    }
    operator fun component2(): Double {
        return this.price
    }
}

operator 关键字可以用来重载操作符或者实现一个约定。这里就是实现了一个约定。这样写之后就可以像 data class 一样进行解构了。Kotlin 的这种解构方式用的比较多的地方是在 Map 数据结构中,它不需要像 Java 一样先拿到 Entry 对象,然后才能拿到 key 值和 value 值,直接用这种解构即可。

// code 5
val person = mapOf<String, String>("name" to "Jack", "age" to "23")
for ((key, value) in person) {
    println("key: $key ==== value: $value")
}    // (是不是比 Java 方便多了?)


2. Kotlin 枚举类(密闭类)


Kotlin 中也有枚举类,使用方法与 Java 的枚举类一样,此外,Kotlin 还有一个更加强大的枚举类,称为密闭类,用 sealed 关键字修饰。密闭类可以有自己的子类,而且可以扩展它的子类,例如给子类设置一些参数等,要知道,枚举类是不具有这种特点的:

// code 6
// Kotlin 密闭类(高级枚举类)
sealed class Language {
    object English: Language()
    object Japanese: Language()
    class Chinese(var isDialect: Boolean): Language()    // 是否方言
}


3. Kotlin 循环写法


这个就没啥可说了,直接上代码!

// code 7
    for (i in 1..10) {    // 注意  x..y 表示的是 x<= i <= y,都是闭区间,且 x <= y,否则 i 为空
        print("$i ")    // 输出 1 2 3 4 5 6 7 8 9 10
    }
    for (i in 1 until 10) {    // 区间为 前闭后开
        print("$i ")    // 输出 1 2 3 4 5 6 7 8 9 
    }
    for (i in 10 downTo 1) {    // 递减循环
        print("$i ")    // 输出 10 9 8 7 6 5 4 3 2 1 
    }
    for (i in 1..10 step 2) {    // step 为步进长
        print("$i ")    // 输出 1 3 5 7 9 
    }
    repeat(10) {    // 高阶函数,大括号里表示的是 Lambda 表达式,传进的参数为循环执行这个表达式多少次,it 表示的是目前执行的是第几次,从 0 开始
        print(it)    // 输出 0123456789
    }
    // 平时用的比较多的还是取集合中的元素
    val list = listOf("I","am","Chinese")
    for (str in list) {
        print("$str ")
    }
    for ((index, str) in list.withIndex()){
        print("第${index}元素是$str")
    }


目录
相关文章
|
6天前
|
数据安全/隐私保护 Kotlin
Kotlin - 类成员
Kotlin - 类成员
40 6
|
5天前
|
Java Kotlin
Kotlin - 类及成员的可见性
Kotlin - 类及成员的可见性
|
6天前
|
Java Kotlin 索引
Kotlin - 分支与循环
Kotlin - 分支与循环
|
8天前
|
Java Kotlin
Kotlin - 类及成员的可见性
Kotlin - 类及成员的可见性
23 5
|
6天前
|
数据安全/隐私保护 Kotlin
Kotlin - 类成员
Kotlin - 类成员
16 2
|
5天前
|
存储 前端开发 Java
Kotlin - 数据类
Kotlin - 数据类
10 0
|
6天前
|
Java Kotlin 索引
Kotlin - 分支与循环
Kotlin - 分支与循环
15 0
|
1月前
|
JSON 调度 数据库
Android面试之5个Kotlin深度面试题:协程、密封类和高阶函数
本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点。文章详细解析了Kotlin中的协程、扩展函数、高阶函数、密封类及`inline`和`reified`关键字在Android开发中的应用,帮助读者更好地理解和使用这些特性。
20 1
|
2月前
|
Android开发 开发者 Kotlin
告别AsyncTask:一招教你用Kotlin协程重构Android应用,流畅度飙升的秘密武器
【9月更文挑战第13天】随着Android应用复杂度的增加,有效管理异步任务成为关键。Kotlin协程提供了一种优雅的并发操作处理方式,使异步编程更简单直观。本文通过具体示例介绍如何使用Kotlin协程优化Android应用性能,包括网络数据加载和UI更新。首先需在`build.gradle`中添加coroutines依赖。接着,通过定义挂起函数执行网络请求,并在`ViewModel`中使用`viewModelScope`启动协程,结合`Dispatchers.Main`更新UI,避免内存泄漏。使用协程不仅简化代码,还提升了程序健壮性。
76 1
|
3月前
|
调度 Android开发 开发者
【颠覆传统!】Kotlin协程魔法:解锁Android应用极速体验,带你领略多线程优化的无限魅力!
【8月更文挑战第12天】多线程对现代Android应用至关重要,能显著提升性能与体验。本文探讨Kotlin中的高效多线程实践。首先,理解主线程(UI线程)的角色,避免阻塞它。Kotlin协程作为轻量级线程,简化异步编程。示例展示了如何使用`kotlinx.coroutines`库创建协程,执行后台任务而不影响UI。此外,通过协程与Retrofit结合,实现了网络数据的异步加载,并安全地更新UI。协程不仅提高代码可读性,还能确保程序高效运行,不阻塞主线程,是构建高性能Android应用的关键。
61 4