1、定义包
和Java不同的是Kotlin
例如,Test.kt文件放在项目的com.kotlin.demo文件夹下,但是包名可以写为com.kotlin.test。
例如,文件名为Test.kt,里面可以这样定义
package com.kotlin.test
class Hello
2、定义函数
程序的入口和java 一样 都是函数
Java 写法:
package com.java;
public class Main {
public static void main(String[] args) {
System.out.println("hello Java");
}
}
kotlin写法:
package com.kotlin
fun main(args: Array<String>) {
println("hello Kotlin")
}
- Kotlin每个语句末尾都不需要加分号(;)
- 方法定义前面用fun 根javascript 的function 很像
定义方法
Java 写法:
public int sum(int a,int b){
return a+b;
}
kotlin写法:
fun sum(a: Int, b: Int): Int {
return a + b
}
可见性修饰符默认为public
Kotlin不返回任何值的写法: Unit 相当于java中的void
fun test(a: Int, b: Int): Unit {
println(a+b)
}
Unit可以省略:
fun test(a: Int, b: Int) {
println(a+b)
}
Kotlin可以将表达式作为函数体,返回:
fun add(a:Int,b:Int) = a + b
3、常量、变量、字符串模板
可变变量,可赋值改变
只读变量,相当于java中的 final,不可赋值后改变
var <propertyName>[: <PropertyType>] [= <property_initializer>]
其初始器(initializer)是可选的。属性类型如果可以从初始器 中推断出来,也可以省略。
- Java变量定义写法:
可变变量
String name = "test";
不可变变量
final String name = "test";
- Kotlin变量定义写法:
可变变量:
立即赋值
var name:String = "test"
先定义后赋值
var name:String
name = "test"
变量可以被推断出类型:
var name = "test"
不可变变量:
val name:String = "test"
- 局部变量只声明,不赋值,在编译阶段Java和Kotlin都会报错(不调用这个变量的话,不会报错)。
- 类的成员变量只声明,不赋值,Java中会被赋一个初始值,Kotlin会编译报错。提示必须初始化,否则需要将类定义为abstract
- 基本类型
-
Java中有八种基本类型:
byte:8位
short:16位
int:32位
long:64位
float:32位
double:64位
char:单一的 16 位 Unicode 字符
boolean:一位
kotlin没有像java一般的基本数据类型,数值类型为:Int, Float, Double等
-
Kotlin中的基本类型:
Byte:8位
Short:16位
Int:32位
Long:64位
Float:32位
Double:64位
Char
Boolean
Array
String
-
字符串模板
无论是Java还是Android开发,我们都会用到字符串拼接,比如进行日志输出等等。在Kotlin中,字符串模板是支持的,我们可以很轻松的完成一个字符串数组的组成
fun main(args:Array<String>){
var a: Int = 2
val b = 2 值
println("a=$a,b=$b)
val book = Book("Thinking In Java", 59.0f, "Unknown")
val extraValue = "extra"
Log.d("MainActivity", "book.name = ${book.name}; book.price=${book.price};extraValue=$extraValue")
}
5、非空验证
- 在类型后面加上?,即表示这个变量或参数以及返回值可以为 null,否则不允许为变量参数赋值为 null 或者返回 null
- 对于一个可能是 null 的变量或者参数,在调用对象方法或者属性之前,需要加上?,否则编译无法通过。
// var str:String = null // 编译即报错
var str: String? = null
println(str + "--length--" + str?.length)
// 打印结果为null
var str1: String
println(str + "--length--" + str1?.length) // 编译即报错
以前这样写
if (adapter != null) {
List<CmdNotice> list = adapter.getDatas();
if (list != null) {
for (CmdNotice it :list) {
if (it.getId() == notice.getId()) {
it.setStatus(notice.getStatus());
adapter.notifyDataSetChanged();
break;
}
}
}
}
现在这样写
adapter?.datas?.firstOrNull({ it.id == notice.id })?.let {
it.status = notice.status
adapter?.notifyDataSetChanged()
}
4、vararg
、in
、is
、when
关键字
关键字vararg
来表示 可变参数
java 代码
public void showArray(String... strArray){
for (String str : strArray){
println("str="+str);
}
}
java kotlin 代码
fun showArray(vararg strArray: String?): Boolean{
for (str in strArray){
println("str=$str")
}
return false
}
控制流
- Java中支持:for,while,do...while,switch,if...else
- Kotlin支持:for,while,if...else,when
主要介绍下Kotlin的用法:
关键字 in
判断一个对象是否在某一个区间内,或在for 中做遍历
跟Python很像
if (1 in 1..5){
println("in----->") 1 在 1-5之间 只会打印一次1
}
for (i in 1..5){
println("i----->=$i") //会打印出来 1 2 3 4 5
}
for(i in 1 until 5){
println("i-----until>=$i") //左闭右开区间,这里即不包括6
}
for(i in 1..5 step 2){
println("i-----step>=$i") // step定义步长,这里为:1, 3, 5
}
for(i in 5 downTo 3){
println("i-----downTo>=$i") // downTo 作用相当于- 会打印出来 5 4 3
}
关键字 is
字,判断一个对象是否为一个类的实例,与 Java 中的instanceof
关键字类似
fun testIn(obj: Any): Int? {
if (obj is String) {
// 做过类型判断以后,obj会被系统自动转换为String类型
return obj.length
}
if (obj !is Int){
}
return null
}
JAVA
if(view instanceof TextView) {
((TextView) view).setText("text");
}
Kotlin
if(view is TextView) {
(view as TextView).setText("text")
}
事实上,Kotlin 此处可以更简单:
if(view is TextView) {
view.setText("text")
}
kotlin中所有类都有一个共同的父类: Any
注意它不是java.lang.Object,
Any除了 equals()、hashCode()和toString()外没有任何成员
关键字 when
代替 switch
kotlin没有switch语句,when语句可以代替它:
fun testWhen(obj: Any) {
when(obj){
// 这里是lambda表达式
0, 1 -> println("zero or one")
1 -> println("one")
in 2..10 -> print("x is in the range")
"hello" -> println("hello")
is String -> println(obj)
!is Long -> println("not a long value")
else ->println("other value") // 相当于switch中的default,可以省略
}
}
5、for循环
- Java
for (int i = 1; i <= 10 ; i++) { }
for (int i = 1; i < 10 ; i++) { }
for (int i = 10; i >= 0 ; i--) { }
for (int i = 1; i <= 10 ; i+=2) { }
for (int i = 10; i >= 0 ; i-=2) { }
for (String item : collection) { }
for (Map.Entry<String, String> entry: map.entrySet()) { }
- Kotlin
for (i in 1..10) { }
for (i in 1 until 10) { }
for (i in 10 downTo 0) { }
for (i in 1..10 step 2) { }
for (i in 10 downTo 1 step 2) { }
for (item in collection) { }
for ((key, value) in map) { }
6、集合
- 创建集合
- java
final List<Integer> listOfNumber = Arrays.asList(1, 2, 3, 4);
final Map<Integer, String> keyValue = new HashMap<Integer, String>();
map.put(1, "Jack");
map.put(2, "Ali");
map.put(3, "Mindorks");
Java 9
final List<Integer> listOfNumber = List.of(1, 2, 3, 4);
final Map<Integer, String> keyValue = Map.of(1, "Jack",
2, "Ali",
3, "Mindorks");
- Kotlin
val listOfNumber = listOf(1, 2, 3, 4)
val keyValue = mapOf(1 to "Jack",
2 to "Ali",
3 to "Mindorks")
- 遍历集合
- java
for (Car car : cars) {
System.out.println(car.speed);
}
Java 8+
cars.forEach(car -> System.out.println(car.speed));
// Java 7 and below
for (Car car : cars) {
if (car.speed > 100) {
System.out.println(car.speed);
}
}
Java 8+
cars.stream().filter(car -> car.speed > 100).forEach(car -> System.out.println(car.speed));
- Kotlin
cars.forEach {
println(it.speed)
}
cars.filter { it.speed > 100 }
.forEach { println(it.speed)}
7、集合方法
1.1 总数操作
方法作用:
any--判断集合中是否有满足条件 的元素;
all--判断集合中的元素是否都满足条件;
count--查询集合中满足条件的元素个数;
fold--在给定初始值的基础上,从第一项到最后一项进行累加;
foldRight--在给定初始值的基础上,从最后一下到第一项进行累加,与fold只是的方向不同;
forEach--循环遍历元素,元素是it,可对每个元素进行相关操作;
forEachIndexed--循环遍历元素,同时得到元素index(下标);
max--查询最大的元素,如果没有则返回null;
maxBy--获取方法处理后返回结果最大值对应的那个元素的初始值,如果没有则返回null;
min--查询最小的元素,如果没有则返回null;
minBy--获取方法处理后返回结果最小值对应那个元素的初始值,如果没有则返回null;
none--判断集合中是否都不满足条件,是则返回true;
reduce--与fold却别在于没有初始值,或者说初始值为0,从第一项到最后一项进行累加;
reduceRight--从最后一下到第一项进行累加,与reduce只是方向的不同;
sumBy--获取方法处理后返回结果值的总和;
1.2 过滤操作
方法作用:
drop--返回去掉前n个元素后的列表;
dropWhile--返回从第一项起,去掉满足条件的元素,直到不满足条件的一项为止;
dropLastWhile--返回从最后一项起,去掉满足条件的元素,直到不满足条件的一项为止;
filter--过滤掉所有不满足条件的元素;
filterNot--过滤掉所有满足条件的元素;
filterNotNull--过滤掉所有值为null的元素;
slice--过滤掉非指定下标的元素,即保留下标对应的元素过滤List中指定下标的元素(比如这里只保留下标为1,3,4的元素),当过滤list中有元素值大于目标List大小时会出现异常;
take--返回从第一个开始的n个元素;
takeLast--返回从最后一个开始的n个元素;
takeWhile--返回不满足条件的下标前面的所有元素的集合;
1.3 映射操作
方法作用:
flatMap--合并两个集合,可以在合并的时候对迭代元素值it多想要的操作;
groupBy--将集合中的元素按照某个条件分组,返回Map;
map--将集合中的元素通过某个方法转换后的结果存到一个集合中;
mapIndexed--除了得到转换后的结果,还可以拿到index(下标);
mapNotNull--执行方法转换前过滤掉为null的元素;
1.4 元素操作
方法作用:
contains--判断集合中是否有指定元素,有则返回true;
elementAt--查找下标对应的元素,如果下标越界会抛IndexOutOfBoundsException异常;
elementAtOrElse--查找下标对应元素,如果越界会根据方法返回默认值(最大下标经方法后的值);
elementAtOrNull--查找下标对应元素,越界会返回Null;
first--返回符合条件的第一个元素,没有则会抛NoSuchElementException异常;
firstOrNull--返回符合条件的第一个元素,没有返回null;
indexOf--返回指定下标的元素,没有返回-1;
indexOfFirst--返回第一个符合条件的元素下标,没有返回-1;
indexOfLast--返回最后一个符合条件的元素下标,没有返回-1;
last--返回符合条件的最后一个元素,没有则会抛NoSuchElementException异常;
lastIndexOf--返回符合条件的最后一个元素,没有返回-1;
lastOrNull--返回符合条件的最后一个元素,没有返回null;
single--返回符合条件的单个元素,如有没有符合的或符合超过一个分别会抛NoSuchElementException或IllegalArgumentException异常;
singleOrNull--返回符合条件的单个元素,如有没有符合或超过一个,返回null;
1.5 生产操作
方法作用:
partition--根据判断条件是否成立,拆分成两个Pair;
plus--合并两个List,可以用"+"替代;
zip--两个集合按照下标组合成一个个的Pair塞到集合中返回;
unzip--将包含多个Pair的List转换成含List的Pair;
Pair对象的数据组成形式为(first, secord),即Pair(1, 2).first可以取出数据1。
1.6 排序操作
方法作用:
reversed--相反顺序;
sorted--自然排序(升序);
sortedBy--根据方法处理结果进行自然(升序)排序;
sortedDescending--降序排序;
sortedByDescending--根据方法处理结果进行降序排序;
7、操作符
一元操作符
操作符 | 函数 |
---|---|
+a | a.unaryPlus() |
-a | a.unaryMinus() |
!a | a.not() |
a++ | a.inc() |
a-- | a.dec() |
二元操作符
操作符 | 函数 |
---|---|
a + b | a.plus(b) |
a - b | a.minus(b) |
a * b | a.times(b) |
a / b | a.div(b) |
a % b | a.mod(b) |
a..b | a.rangeTo(b) |
a in b | a.contains(b) |
a !In b | !a.contains(b) |
a += b | a.plusAssign(b) |
a -= b | a.minusAssign(b) |
a *= b | a.timesAssign(b) |
a /= b | a.divAssign(b) |
a %= b | a.modAssign(b) |