最近裁员赋闲在家,没事就用Kotlin 刷一下Leetcode,打打Leetcode周赛,功力长进不大仍是只能做一个三题选手。可是也运用kotlin写了快上万行的算法了,学到了不少kotlin的编程技巧,下面我泡一壶茶慢慢说。

初见 Kotlin:

fun main() {
    val name = "Kotlin"
    println("Hello, $name!")
    for (i in 1..5) {
        println("i = $i")
    }
}

上面是一个最基础的 kotlin 程序,也是 kotlin 函数式编程的基本概念。在 kotlin KT 文件里边能够直接界说函数与变量量,其实也没有黑魔法,只是简单的将这一整个文件编译成 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 代码,你觉得他会能够经过编译吗?

fun test(k: Int) {
    k--
}

然后咱们再来看一段Java代码,你觉得他能经过编译吗?

void test(int k){
    k--;
}

假如咱们在电脑上稍微运行一下信任很快就会有答案,可是为什么这么规划?
主要是由于 kotlin 函数规划思想是函数式编程,在函数式编程里边很重要的一点便是要减少副作用

副作用:函数或办法对除了返回值之外的其他部分发生的可观察到的改变

下面咱们看下另一个比如,我在运用kotlin回答算法题的时分常常会这么写:

fun test(arr: IntArray):Int {
    fun test1(n:Int):Int{
        return n*2-arr.size
    }
    return test1(3)
}

这种写法形似看起来很新奇是吗?咱们估量把这种办法界说函数叫做部分函数,关于我个人而言这种写法的最大优点便是能够充分利用所在函数/test 内部的变量,这样咱们在部分函数运用的时分不需要界说许多入参,这种办法在运用 kotlin 进行 Leetcode 算法比赛、回答的时分会有很大优势。第二个优势便是封装了一些细节完成,外部运用者不需要关怀详细逻辑。
最终咱们看一看他的真身吧!

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的时分常常会有这种写法

int a,b=0;

可是 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
}

解构是一个十分有用的操作,他主要意图便是提取一组变量,给咱们开发者省事。
再看另一个比如

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周赛和解题常常运用的一些好用的办法

arr.joinToString(",")

这个办法最好用,他直接在[1,2,3] 数组的中心加上一个字符变成 1,2,3 而不要自己写逻辑去处理末尾的情况,十分有用

arr.distinct()

去重,有用性或许没那么高,一般解题的时分会用到。

arr.sum()
arr.min()
arr.max()
arr.last()
arr.first()
arr.find {  }

上面这几个操作应该归于 Kotlin 开发者有必要掌握的技术了吧
最终来一个 Kotlin 一行代码写前缀和的操作吧

arr.scan(0){acc, i -> acc+i }

再会 and 周末愉快