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) |