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 }
相关推荐
li_liuliu12 分钟前
Android4.4 在系统中添加自己的System Service
android
guitarjoy13 分钟前
Kotlin - 协程结构化并发Structured Concurrency
kotlin·协程·coroutinescope·结构化同步
C4rpeDime2 小时前
自建MD5解密平台-续
android
鲤籽鲲4 小时前
C# Random 随机数 全面解析
android·java·c#
m0_548514778 小时前
2024.12.10——攻防世界Web_php_include
android·前端·php
凤邪摩羯8 小时前
Android-性能优化-03-启动优化-启动耗时
android
凤邪摩羯8 小时前
Android-性能优化-02-内存优化-LeakCanary原理解析
android
喀什酱豆腐9 小时前
Handle
android
m0_7482329210 小时前
Android Https和WebView
android·网络协议·https
m0_7482517210 小时前
Android webview 打开本地H5项目(Cocos游戏以及Unity游戏)
android·游戏·unity