Kotlin开发的100个Tips (三)

前言

这次继续来搞kt,接着kt开发的100个Tips,之前的系列: juejin.cn/post/724929... Kotlin开发的100个Tips (一)
juejin.cn/post/731160... Kotlin开发的100个Tips (二)

21. for循环的until另一种写法 (1.9.0新特性)

平时我们写for循环会有两种写法

scss 复制代码
for (i in 0.. 5)   // 输出 012345

scss 复制代码
for (i in 0 until 5)   // 输出 01234

但是我觉得until这个关键字看上去不太舒服,我现在可以这样写

scss 复制代码
for (i in 0 ..< 5)   // 也是输出 01234

在这个场景下,..<的效果和until的效果一样,但看着会更舒服些

22. 数组的forEach获取数组中的位置

平时我们在java中对List做循环

ini 复制代码
List<String> list = new ArrayList();  
for (int i = 0; i < list.size(); i++) {  
    String a = list.get(i);  
}

但是用kt来写的话一般直接用forEach来做

ini 复制代码
val list = ArrayList<String>()  
list.forEach {  
    val a = it  
}

但是如果我们想在循环中获取index,很多新手不懂怎么写,只能通过像java一样写个for循环,其实list有个方法forEachIndexed

ini 复制代码
val list = ArrayList<String>()  
list.forEachIndexed { index, s ->  
    val a = s  
    val i = index  
}

这样就能获取到index了

23. 创建线程

因为kotlin的lambda表达式的特性,创建线程的写法也会非常的简洁

bash 复制代码
Log.d("mmp","----线程A ${Thread.currentThread().name}")  
Thread{  
    Log.d("mmp","----线程B ${Thread.currentThread().name}")  
}.start()

24. kotlin的关键字注解

比如我们给变量用Volatile修饰,在kotlin中可以这样写

kotlin 复制代码
@Volatile  
private var a: Int? = null

使用一个注解的方法去实现,点开它,发现是一个JvmFlagAnnotation.kt文件,里面还定义了其他注解

less 复制代码
@Target(FIELD)  
@Retention(AnnotationRetention.SOURCE)  
@MustBeDocumented  
public actual annotation class Volatile  
  

@Target(FIELD)  
@Retention(AnnotationRetention.SOURCE)  
@MustBeDocumented  
public actual annotation class Transient  
  

@Target(FUNCTION, CONSTRUCTOR, PROPERTY_GETTER, PROPERTY_SETTER, CLASS)  
@Retention(AnnotationRetention.SOURCE)  
@MustBeDocumented  
public actual annotation class Strictfp  
  

@Target(FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER)  
@Retention(AnnotationRetention.SOURCE)  
@MustBeDocumented  
public actual annotation class Synchronized  
  

@Target(EXPRESSION)  
@Retention(AnnotationRetention.SOURCE)  
@SinceKotlin("1.8")  
public actual annotation class JvmSerializableLambda

Volatile和Synchronized都是用于线程安全,Strictfp用于精确浮点,Transient和JvmSerializableLambda都是用于序列化,其中JvmSerializableLambda是用来序列化lambda表达式。

Volatile、Synchronized、Strictfp和Transient都是java中的关键字,可以看出kt使用注解的方式去实现这个效果。

25. 获取数组的第一个元素

这个是业务上基本都会有的一个小操作,比如说本来后台应该返回一个对象的,但是因为一些原因他和你说他会返回一个数组,你拿数组中第一个元素就行。或者后台返回一个有序数组,我们只需要拿数组中的最大/最小元素,就是拿第一个就行。如果你细心观察,你会发现业务上会有这样的场景存在。

如果用Java来做这个功能,我们可能需要写

scss 复制代码
if(list != null && list.size() > 0)

但是kt能快速的实现这个效果

ini 复制代码
val first = list?.firstOrNull()

这样的写法看起来又舒服,代码也整洁,也安全,不管list是空,还是list数组为空,还是list的第一个元素是空,都会返回空。

26. takeIf 带逻辑的判断

这个关键字的使用场景比较微妙,如果不熟的话,很多场景可以用你也会想不到要用他,所以这个是一个偏经验的关键字。简单来说,就是用在一些复杂的判断场景。

(可以写一段伪代码)假如我有个变量存在本地,这个对象包含了日期、次数、用户id,我要判断日期是今天并且次数小于3,才拿这个用户id去做一些操作

kotlin 复制代码
val userId = SpUtils().get("key")?.takeId{
    return DateUtlis.isToday(it.date) && (it.count < 3)
}?.id

如果条件达成,就能正常拿到id,如果不达成条件,userId就会为空。除此之外还有takeUnless可以辅助takeIf来使用,这里就不多介绍了。

27. 数组做补全操作

可能会有一些需求,比如我要显示9张卡片,由服务端返回卡片列表,如果不满九张的话,没有的卡片就显示+号,那么就需要做一些数组补全的操作。

kt中可以快速实现这个效果

ini 复制代码
val list = getServiceList()
val paddedList = list + List(9 - list.size) { null }

这样在recyclerview的Item中判断数据为空就显示+号

28. data类的get方法

平时我们写data都是这样写

kotlin 复制代码
data class User(var name : String?)

但是假设我想调用user.name获取参数的时候做一些操作,返回不同的结果,我就需要在getName()中做操作,那对于data类要怎么去写它的某个属性的get方法呢,其实可以这样写

kotlin 复制代码
data class User(var id : String?){
    @SerializedName("name")  
    var name: String? = null  
        get() {  
            return NicknameCache.getNickName(id) ?: field  
        }
}

29. 使用标签辅助跳出多层循环

kotlin中可以使用标签来跳出多层判断或者多层循环,当然不用标签也是能实现的,只不过会显得代码比较复杂,而且使用标签的话,一眼就能看出跳出哪一层,并且代码也相对简洁

例如可以这样写

kotlin 复制代码
loop@ for (i in 1..3) {
    for (j in 1..3) {
        if (i == 2 && j == 2) {
            break@loop // 使用标签来跳出外部循环
        }
    }
}

这里的loop@就是标签,break@loop就会跳到外层的for循环。

30. 交换变量

这个是一个小技巧,一般的的业务功能是很少出现这种场景,但是涉及算法和优化的场景,是会涉及到两个变量交互。

正常来说,我们按照Java的思路会这样写

ini 复制代码
var temp = a
a = b
b = temp

用一个中间变量来辅助交换,但是在kt中可以这样做

css 复制代码
a = b.apply { b = a }
相关推荐
你听得到1120 分钟前
肝了半个月,我用 Flutter 写了个功能强大的图片编辑器,告别image_cropper
android·前端·flutter
KevinWang_20 分钟前
Android 原生 app 和 WebView 如何交互?
android
用户693717500138422 分钟前
Android Studio中Gradle、AGP、Java 版本关系:不再被构建折磨!
android·android studio
杨筱毅1 小时前
【底层机制】Android低内存管理机制深度解析
android·底层机制
二流小码农2 小时前
鸿蒙开发:this的指向问题
android·ios·harmonyos
循环不息优化不止2 小时前
Jetpack Compose 状态管理
android
友人.2274 小时前
Android 底部导航栏 (BottomNavigationView) 制作教程
android
努力学习的小廉4 小时前
初识MYSQL —— 事务
android·mysql·adb
阿里云云原生4 小时前
深度解析 Android 崩溃捕获原理及从崩溃到归因的闭环实践
android
.豆鲨包4 小时前
【Android】Android内存缓存LruCache与DiskLruCache的使用及实现原理
android·java·缓存