kotlin入门最容易教程一(最全,最详细)
Kotlin与Java的异同(一)
Kotlin学习(一):Kotlin基础知识
一.Kotlin之基础语法
Kotlin零基础入门到精通(精选)
手把手教使用kotlin+Gradle+springboot进行后端开发,并通过docker部署到linux。
springboot+kotlin+gradle+jooq的学习笔记
如何把Kotlin代码转成java代码,如何把java代码转成kotlin代码
kotlin与java的区别
Kotlin系列之let、with、run、apply、also函数的使用
Gradle入门及SpringBoot项目构建
Kotlin细节十五:作用域函数与 this it 关键字
Kotlin系列一:基础知识快速入门
Kotlin 基础专栏
Kotlin 基础语法
Kotlin基本知识:类-继承-接口…ST
Kotlin快速入门(五)继承、接口、多态
Java过渡Kotlin05:继承和接口
kotlin继承与多态
(二十)Kotlin简单易学 基础语法-抽象类
kotlin 抽象类(Abstract)和接口(Interface)
Kotlin 中级篇(七):抽象类(abstract)、内部类(嵌套类)
Kotlin 与 Java 相互调用
初步了解JOOQ并实现简单 - - - CRUD(一)
JOOQ用法和实例
Kotlin集合详解
Kotlin 中的集合的方法
Kotlin笔记18–集合的函数式API–map函数
class Test2 {
fun sayHi1(name: String) {
println("Hi,$name")
}
fun sayHi(name: String) = println("Hi,$name")
}
val sum1 = { a: Int, b: Int -> a + b }
fun main() {
val t = Test2()
t.sayHi("zhangsan")
Test2().sayHi1("lisi")
println(sum1(2, 3))
print(sum1.invoke(2, 3))
}
package com.inkrich.admin.api.controller.v1
import java.util.*
object test {
@JvmStatic
fun main(args: Array<String>) {
println(System.currentTimeMillis())
val arr = intArrayOf(2, 3, 4)
println("arr = ${arr}")
val list: MutableList<Int> = ArrayList<Int>()
list.add(11)
list.add(22)
println("list = ${list}")
for (i in 0..4) {
println("i = $i")
}
val list1 = arrayListOf("10", "11", "111")
val map: MutableMap<String?, String?> = HashMap<String?, String?>()
map["1"] = "zhangsan"
val i = Random().nextInt(10)
println("i = $i")
val languages = arrayListOf("java")
languages.add("kotlin")
languages.add("php")
println("languages = ${languages}")
}
}
class Test6 {
fun getScore(name: String) = when (name) {
"TOM" -> 86
"JIM" -> 77
"Jack" -> 95
"Lily" -> 100
else -> 0
}
fun checkNumber(num: Number) {
when (num) {
is Int -> println("number is Int")
is Double -> println("number is Double")
else -> println("number not support")
}
}
}
fun main() {
println(Test6().getScore("JIM"))
println(getScore("L"))
val c = Test6()
println(c.checkNumber(14))
val range = 1..5
val range1 = 0 until 6
for (i in range){
println("i = $i")
}
for (i in range1){
println("i = ${i}")
}
}
private fun doSomething(i:Int ,s:String):String{
return "resultCode";
}
fun main() {
val flag = doSomething(5, "abc")
println(flag)
}
//resultCode
class Test12 {
}
fun doSomething1(i: Int, s: String): String {
return "$s $i";
}
fun main() {
val flag = doSomething1(5, "abc")
println(flag)
}
//abc 5
class Test13 {
fun doSomething2(i: Int, s: String): String {
return "$s $i";
}
}
fun main() {
val flag = Test13().doSomething2(5, "abc")
println(flag)
}
//abc 5
private fun doSomething2(a:Int=2,s:String="null"):String{
return "$a $s";
}
fun main() {
//没有传任何参数
val result = doSomething2()
println(result)
}
//2 null
NoClassDefFoundError exception when calling Java code from Kotlin
将java文件放到java文件夹里,不要放到kotlin文件夹里!!!!
java文件
import java.util.Arrays;
//Java
public class Data {
String is;
public String getIs() {
return is;
}
public void setIs(String is) {
this.is = is;
}
public void in() {
System.out.println("call java method in");
}
public void multiParams(int... params) {
System.out.println(Arrays.toString(params));
}
}
kotlin文件
// kotlin
fun main() {
// 1. java 中的方法或变量 是kotlin 的关键字时,使用反引号 `` 对关键字进行转义
val demo = Data()
// 调用 java 的 is 属性,is 是 kotlin 的关键字,使用反引号转义
demo.`is` = "call java field"
println(demo.`is`) // call java field
// 调用 java 的 in 方法,in 是 kotlin 的关键字,使用反引号转义
demo.`in`() // call java method in
}
这里说的 map 函数和集合 Map 是两回事,不要混淆!
集合的函数式 API ,常用的就是 map 函数,这里罗列一些功能。
import java.util.*
fun main() {
val list = listOf("Apple", "Banana", "Cherry", "Durian", "Orange", "Pear", "Watermelon")
val newList1 = list.map { it.toUpperCase() }
val newList2 = list.map { it.toUpperCase(Locale.ROOT) }
println("list = ${list}")
println("newList1 = ${newList1}")
println("newList2 = ${newList2}")
val numbers1 = listOf(1, -2, 3, -4, 5, -6)
numbers1.forEach { print("$it ") }
//输出 :1 -2 3 -4 5 -6
println("")
val doubled = numbers1.map { x -> x * 2 }
doubled.forEach { print("$it ") }
//输出 :2 -4 6 -8 10 -12
println("")
val tripled = numbers1.map { it * 3 }
tripled.forEach { print("$it ") }
//输出 3 -6 9 -12 15 -18
val numbers = listOf(1, -2, 3, -4, 5, -6)
numbers.forEach{ print("$it ")}
//输出 :1 -2 3 -4 5 -6
println("")
val positives = numbers.filter { x -> x > 0 }
positives.forEach{ print("$it ")}
//输出 :1 3 5
println("")
val negatives = numbers.filter { it < 0 }
negatives.forEach{ print("$it ")}
//输出 :-2 -4 -6
}
这个和C语言的函数指针是非常像似的,但java是移除了这些特性的。
我们看下面的代码,第一次看这个代码可能非常的奇怪,看着像lambda表达式,又不完全是,其实这里的关键就是理解()->String的含义。这个语法是lambda表达式,但这里的真正含义是匿名内部类类型,并且这个匿名内部类返回String类型。顺理成章的,我们定义的变量result的类型也就变成了String类型。注意是一个类型声明,而不是lambda表达式实体,lambda表达式的实体是{}里面的内容。
var result:()->String={
val animal="dog"
"This is $animal"
}
看下和lambda表达式的对比:
下面是java的lambda表达式.一个非常明显的区别就是kotlin的匿名内部类没有return,而且在里面也是不可以写return的,这是因为他默认返回类型是表达式的最后一行。为了实现这个功能,就必须显示的声明类型,因为可能返回一个类对象。
()->{
val animal="dog"
return "This is $animal"
}
当然也是可以带参数的。在()里面声明参数类型,在{}开头可以写具体名字。写法还是非常飘逸的。
val result2:(String,Int)->String={
name,age->
val animal="dog"
"This is $animal , name is $name , age is $age"
}
println(result2("tom",5))
还有一种类型推断的写法,如下,参数我们还是要指定类型的,但返回值可以推断出来。感觉这种写法更简洁一点,前面的写法更标准一些。
val result4 = { name: String, age: Int ->
val animal = "dog"
"This is $animal , name is $name , age is $age"
}
var result1:()->String={
val animal="dog"
"This is $animal"
}
val result2: (String, Int) -> String = { name, age ->
val animal = "dog"
"This is $animal , name is $name , age is $age"
}
val result4 = { name: String, age: Int ->
val animal = "dog"
"This is $animal , name is $name , age is $age"
}
fun main() {
println(result1())
println(result2("tom", 5))
println(result4("jack", 6))
}
//This is dog
//This is dog , name is tom , age is 5
//This is dog , name is jack , age is 6
接着上小节,如果参数只有一个的时候,我们可以不写具体的参数名字,kotlin默认为我们提供了一个it关键字,可以直接使用这个关键字当参数变量名称。
val result3:(String)->String={
val animal="dog"
"This is a $animal , name is $it."
}
println(result3("tom"))
//This is a dog , name is tom.
下面这个函数的功能是显示学生信息,包括学生的姓名和身份证,第二个参数是一个函数类型,没错可以将一个函数做为参数传进来。这个函数可以合成学生的身份证,身份证由邮政编码,生日,编号构成。
private fun showStudentInfo(name: String, getId: (Int, Int, Int) -> String): String {
//必须用大括号
return "$name's id is ${getId(300027, 20001212, 1001)}"
}
fun main() {
var getId = { code: Int, birth: Int, num: Int ->
"$code$birth$num"
}
println(showStudentInfo("Tom", getId))
//Tom's id is 300027200012121001
}
其实这个写法非常的奇怪。声明一个函数然后又去调用,那干嘛不直接写一个函数呢?其实,上面的写法是不合理的,一般不会这么写,问题就出在var getId这个变量上,我们写了这个变量来引用函数类型,这是没有必要的,因为我们用函数类型的目的就是为了写匿名函数,取名字完全是多此一举。可以简化写成下面的样子。
println(showStudentInfo("Tom", { code, birth, num ->
"$code$birth$num"
}))
这样看起来就是非常简洁了。而且,kotlin有规定,如果只有一个函数类型,或者函数类型是最后一个,()可以省略。
函数类型是最后一个的情况:
println(showStudentInfo("Tom") { code, birth, num ->
"$code$birth$num"
})
只有一个函数类型做参数的时候
println(showStudentInfo { code, birth, num ->
"$code$birth$num"
})
总结
private fun showStudentInfo(name: String, getId: (Int, Int, Int) -> String): String {
//必须用大括号
return "$name's id is ${getId(300027, 20001212, 1001)}"
}
private fun showStudentInfo1( getId: (Int, Int, Int) -> String): String {
//必须用大括号
return "Jack's id is ${getId(300027, 20001212, 1001)}"
}
fun main() {
println(showStudentInfo("Tom", { code, birth, num ->
"$code$birth$num"
}))
//Tom's id is 300027200012121001
println(showStudentInfo("Tom") { code, birth, num ->
"$code$birth$num"
})
println(showStudentInfo1 { code, birth, num ->
"$code$birth$num"
})
}
Tom's id is 300027200012121001
Tom's id is 300027200012121001
Jack's id is 300027200012121001
这种写法一定要掌握,因为这个写法在kotlin里面是非常常见的。
这种写法一定要掌握,因为这个写法在kotlin里面是非常常见的。
这种写法一定要掌握,因为这个写法在kotlin里面是非常常见的。
内联函数的主要用途就是为匿名函数提高性能。在调用下面的有函数类型做为参数的方法时,会使用到匿名内部类。第二个参数要求我们传入匿名内部类,对于编译器来说,匿名内部类的创建和普通类是一样的,但既然是匿名的,效率应该要更高写,如果也是和普通类一样创建,效率就比较低了。内联函数就是为了解决这个性能问题,那么是怎么解决的呢?答案是通过宏替换,如果你学过C语言,你就知道C语言的宏替换,内联函数也是一样的,通过宏替换,我们直接把匿名内部类的代码直接复制到调用的函数里面,这样就不需要创建类了,不需要创建类当然性能就提高了。
使用方法就是直接添加一个inline关键字就可以了。
private inline fun showStudentInfo(name: String, getId: (Int,Int,Int) -> String): String {
return xxx
}
在调用含有函数类型的方法时,不光可以传入匿名内部类,也可以传通常的方法,这时候就需要用到函数引用。
例如下面的代码,foo方法的参数列表和showStudentInfo里面的getId函数类型的参数列表是一样的,这个时候可以把foo直接传给showStudentInfo。使用方法就是在::加普通函数名称。
private fun showStudentInfo(name: String, getId: (Int, Int, Int) -> String): String {
//必须用大括号
return "$name's id is ${getId(300027, 20001212, 1001)}"
}
private fun foo(a: Int, b: Int, c: Int): String {
return "$a$b$c"
}
fun main() {
println(showStudentInfo("Tom", ::foo))
}
id is 300027200012121001
简单来说,就是一个函数返回另一个函数。什么?这有什么意义?如果有多个函数进行嵌套调用,那么就会形成函数之间的层层包含关系。这样的好处就是子函数可以共享父函数的变量,这种写法在脚本语言中是非常常见的,例如JavaScript。这样做的原因是脚本语言存在一个很大的问题,就是即使在不同的文件里面定义相同的变量名也会报错。因为脚本语言并没有像java这样有package和class的概念。kotlin也可以做为脚本语言。我们只能举个简单的例子来说明一下她的形式,理解的比较深还是需要大量的实践的。
看下面的代码,返回值是一个函数类型,传入一个String返回String。
private fun foo(a:Int):(String)->String{
return {
"$it"
}
}
在main函数中执行,返回函数类型的变量bar,可以调用,传入"abc"返回"abc"
var bar = foo(1)
println(bar.invoke("abc"))
输出:
abc
【Kotlin備忘録】コレクション関数 map, filter + おまけ
[Kotlin]Map / MutableMapの特徴と使い方
fun main() {
var files1 = mutableListOf<String?>()
var files2: List<String>? = null
println("files1 = ${files1}")//files1 = []
println("files2 = ${files2}")//files2 = null
}
例子1
fun main() {
val fruits = listOf("Strawberry", "Grape", "Orange")
// fruits の各要素に文字列を追加したListを作成
val greatFruits = fruits.map {
"Great $it!" // <- 各要素は"it"として取得できる
}
println(fruits)
println(greatFruits)
}
结果1
[Strawberry, Grape, Orange]
[Great Strawberry!, Great Grape!, Great Orange!]
例子2
fun main() {
val pricesByFruit = mapOf("Strawberry" to 4.5, "Grape" to 5.1, "Orange" to 3.0)
// 既存のMapのキーと値を入れ替えたMapを作成する
val fruitByPrice = pricesByFruit.map {
// pricesByFruitの各要素の値を利用したPairを作成し、Listの1要素として取得
it.value to it.key
}.toMap() // <- そのままだとListが戻り値になるため、toMap()でMapに変更する
println(pricesByFruit)
println(fruitByPrice)
}
结果2
{Strawberry=4.5, Grape=5.1, Orange=3.0}
{4.5=Strawberry, 5.1=Grape, 3.0=Orange}
コレクションの各要素について、結果に合致するListを取得します。
fun main() {
val fruits = listOf("Strawberry", "Grape", "Orange")
val gFruits = fruits.filter {
// 要素をすべて小文字にし、大文字小文字関係なく"g"が入っているかをチェック
it.toLowerCase().contains("g") // <- 各要素は"it"として取得できる
}
println(fruits)
println(gFruits)
}
[Strawberry, Grape, Orange]
[Grape, Orange]