最近裁员赋闲在家,没事就用Kotlin 刷一下Leetcode,打打Leetcode周赛,功力长进不大还是只能做一个三题选手。但是也使用kotlin写了快上万行的算法了,学到了不少kotlin的编程技巧,下面我泡一壶茶慢慢说。
初见 Kotlin:
kotlin
fun main() {
val name = "Kotlin"
println("Hello, $name!")
for (i in 1..5) {
println("i = $i")
}
}
上面是一个最基础的 kotlin 程序,也是 kotlin 函数式编程的基本概念。在 kotlin KT 文件里面可以直接定义函数与变量量,其实也没有黑魔法,只是简单的将这一整个文件编译成 class。
class
public final class MainKt {
public static final void main() {
String name = "Kotlin";
String var1 = "Hello, " + name + '!';
System.out.println(var1);
for(int i = 1; i < 6; ++i) {
String var2 = "i = " + i;
System.out.println(var2);
}
}
// $FF: synthetic method
public static void main(String[] args) {
main();
}
}
但是为什么这么写是我们值得思考的问题,其中非常重要的一点就是为了满足 kotlin 函数式编程设计初衷。在kotlin 中很多方式是可以找到与Java里面类似的对应的,但是我并不建议大家这么理解。很多时候我们可以尝试用kotlin的方式来思考。Btw kotlin 里面的 fun 跟Java 里面的方法不是完全等价的,后面会逐步跟大家说道。
又见kotlin
下面看两段你可能天天见的代码,却又没有注意到的一点点细节。首先我们来看一段 kotlin 代码,你觉得他会可以通过编译吗?
kotlin
fun test(k: Int) {
k--
}
然后我们再来看一段Java代码,你觉得他能通过编译吗?
Java
void test(int k){
k--;
}
如果大家在电脑上稍微运行一下相信很快就会有答案,但是为什么这么设计? 主要是由于 kotlin 函数设计思想是函数式编程,在函数式编程里面很重要的一点就是要减少副作用
副作用:函数或方法对除了返回值之外的其他部分产生的可观察到的变化
下面我们看下另一个例子,我在使用kotlin解答算法题的时候经常会这么写:
kotlin
fun test(arr: IntArray):Int {
fun test1(n:Int):Int{
return n*2-arr.size
}
return test1(3)
}
这种写法貌似看起来很新奇是吗?我们估计把这种方式定义函数叫做局部函数,对于我个人而言这种写法的最大好处就是可以充分利用所在函数/test 内部的变量,这样我们在局部函数使用的时候不需要定义很多入参,这种方式在使用 kotlin 进行 Leetcode 算法竞赛、解答的时候会有很大优势。第二个优势就是封装了一些细节实现,外部使用者不需要关心具体逻辑。 最后我们看一看他的真身吧!
java
public static final int test(@NotNull int[] arr) {
Intrinsics.checkNotNullParameter(arr, "arr");
return test$test1(arr, 3);
}
private static final int test$test1(int[] $arr, int n) {
return n * 2 - $arr.length;
}
Kotlin 天天见
在定义变量的时候以前我们使用Java的时候经常会有这种写法
Java
int a,b=0;
但是 kotlin 似乎没有这样的操作,如果我们要实现类似的操作可以怎么做呢?
我们可以使用 kotlin 新特性 解构
kotlin
data class Student(val name:String,val age:Int)
fun test(arr: IntArray,student: Student):Int {
//var (a,b) = 0 to 0
//var (a,b) = intArrayOf(0,0)
var (a,b) = mutableListOf(0,0)
val (name,age) = student
return 0
}
解构是一个非常实用的操作,他主要目的就是提取一组变量,给我们开发者省事。 再看另一个例子
kotlin
fun test():Int {
val map = mutableMapOf<String,Int>("张三" to 18,"小帅" to 20,"丧彪" to 30)
for ((name,age) in map){
println("name$name age$age")
}
return 0
}
这样食用 kotlin 是不是就舒服多了,代码写的少了,逻辑更清晰了。
Kotlin 明天见
最后分享一下本人平时使用 Kotlin 打Leetcode周赛和解题经常使用的一些好用的方法
Kotlin
arr.joinToString(",")
这个方法最好用,他直接在[1,2,3] 数组的中间加上一个字符变成 1,2,3 而不要自己写逻辑去处理末尾的情况,非常实用
Kotlin
arr.distinct()
去重,实用性可能没那么高,一般解题的时候会用到。
Kotlin
arr.sum()
arr.min()
arr.max()
arr.last()
arr.first()
arr.find { }
上面这几个操作应该属于 Kotlin 开发者必须掌握的技能了吧 最后来一个 Kotlin 一行代码写前缀和的操作吧
Kotlin
arr.scan(0){acc, i -> acc+i }
再见 and 周末愉快