基本類型的數組 是沒有自動裝箱拆箱的過程,而list是有的
對於基本類型使用,推薦用數組,性能會好點
kotlin裝箱須要根據場合
對於 Int 這樣的基本類型,儘可能用不可空變量
var a: Int = 1 // unbox
var b: Int? = 2 // box 會轉成 Integer.parse(2) 執行裝箱
var list: List<Int> = listOf(1, 2) // box
知足如下條件就不會執行裝箱
1 不可空類型
2 使用 IntArray FloatArray複製代碼
kotlin 數組不支持協變 就是子類數組對象不能賦值給父類的數組變量
在kotlin 數組的寫法變成 泛型式寫法 arrayOf("","","")
var array: IntArray = intArrayOf(1, 2) //這種是 unbox 的
kotlin 裏用專門的基本類型數組類 (IntArray FloatArray LongArray) 才能夠免於裝箱拆箱。
元素不是基本類型時,相比 Array,用 List 更方便些
複製代碼
支持協變 指的是:子類類型的list 能夠賦值給父類的list
List 以固定順序存儲一組元素,元素能夠重複。 ===>listOf("a", "b", "c") 支持協變
Set 存儲一組互不相等的元素,一般沒有固定 順序. ===>setOf("a", "b", "c") 支持協變
Map 存儲 鍵-值對的數據集合,鍵互不相等,但不一樣的鍵能夠對應相同的值。
var map = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key4" to 3)
map.put("key1", 2)
map["key1"] = 2
val value1 = map.get("key1")
val value2 = map["key2"]
操做函數: forEach filter map flamap
惰性集合sequenceOf 只有使用的使用時候纔會執行複製代碼
list相對於數組 功能更豐富,可是數組基本類型的數組是沒有自動裝拆箱過程,而list是有的,
對於基本類型 ,數組的性能會比list好.
在kotlin ,要用專門的數組類才能免於自動裝拆箱 (IntArray FloatArray LongArray)複製代碼
集合分爲兩種類型:只讀的和可變的。這裏的只讀有兩層意思:
java
如下是三種集合類型建立不可變和可變實例的例子:數組
listOf()
建立不可變的 List
,mutableListOf()
建立可變的 List
。setOf()
建立不可變的 Set
,mutableSetOf()
建立可變的 Set
。mapOf()
建立不可變的 Map
,mutableMapOf()
建立可變的 Map
。toMutable*()
系函數轉換成可變的集合,返回的是一個新建的集合,原有的集合仍是不可變的,因此只能對函數返回的集合修改。
主構造器的參數聲明時加上 var 或者 val,就等價於在類中建立了該名稱的屬性
1 類默認是public final, 標識符 : 不只能夠表示繼承,還能夠表示 Java 中的 implement 基類Any
2 構造函數單獨用了一個 constructor 關鍵字來和其餘的 fun 作區分。
3 Kotlin 裏的類默認是 final 的,是不可繼承的 須要open 聲明
4 override 是有遺傳性的(若是要關閉 子類的方法寫成final override機可),open 沒有遺傳性
5 open 與 abstract關鍵字區別,abstract修飾的類沒法直接實例化,須要被繼承
6 類型判斷及強轉 is 、as、as?(可空類型使用)
7 init 代碼塊是緊跟在主構造器以後,先於次構造器執行的
8 把主構造器當作身體的頭部,那麼 init 代碼塊就是頸部,次構造器就至關於身體其他部分。
9 關鍵字var val const open constructor overrider abstract Any objcet 修飾的類是單例類 ,(對象申明 對象表達)單例餓漢式的單例,而且實現了線程安全。
10 修飾符
11 kotlin實現匿名類寫法
val listener = object: ViewPager.SimpleOnPageChangeListener() {
override fun onPageSelected(position: Int) {
// override
}
}
public:公開,可見性最大,哪裏均可以引用。
private:私有,可見性最小,根據聲明位置不一樣可分爲類中可見和文件中可見。
protected:保護,至關於 private + 子類可見。
internal:內部,僅對 module 內可見。
@hide 限制客戶端訪問複製代碼
若是類中有主構造器,那麼其餘的次構造器都須要經過 this
關鍵字調用主構造器,能夠直接調用或者經過別的次構造器間接調用。若是不調用 IDE 就會報錯:
安全
class User constructor(var name: String) {
constructor(name: String, id: Int) {
// 👆這樣寫會報錯,Primary constructor call expected
}
}
從主構造器的特性出發,一旦在類中聲明瞭主構造器,就包含兩點必須性:建立類的對象時,無論使用哪一個次構造器,
都須要主構造器的參與第一性:
在類的初始化過程當中,首先執行的就是主構造器若是把主構造器當作身體的頭部,那麼 init 代碼塊就是頸部,
次構造器就至關於身體其他部分。
若是在主構造器的參數聲明時加上 var 或者 val,就等價於在類中建立了該名稱的屬性(property)
而且初始值就是主構造器中該參數的值。複製代碼
class Sample {
companion object {
👇 // 👇
const val CONST_NUMBER = 1
}
}
const val CONST_SECOND_NUMBER = 2 編譯期常量
Kotlin 的常量必須聲明在對象(包括伴生對象)或者「top-level 頂層」中,由於常量是靜態的。
Kotlin 新增了修飾常量的 const 關鍵字。
Kotlin 中只有基本類型和 String 類型能夠聲明成常量。
val 只表示只讀複製代碼
juejin.im/post/5d70a2… 這裏單獨做了筆記
bash
若是寫工具類 那就直接建立一個文件 在top-level層聲明ide
若是隻是針對類,而不是針對外部使用者 就能夠寫成 companion object 或者object函數
fun login(user: String, password: String, illegalStr: String) {
👇
fun validate(value: String, illegalStr: String) {
if (value.isEmpty()) {
throw IllegalArgumentException(illegalStr)
}
}
👇
validate(user, illegalStr)
validate(password, illegalStr)
}
這裏將共同的驗證邏輯放進了嵌套函數 validate 中,
而且 login 函數以外的其餘地方沒法訪問這個嵌套函數。複製代碼
any
data 數據類 自動生成getset
inner 內部類申明 區別於嵌套類是能夠訪問外部類成員
object
sealed
open
constructor
require
inline
suspend 掛起提醒函數 在協程與withContext配套使用
tailrec 搭配尾遞歸函數,函數的最後一行是函數調用的場景,是遞歸的一種特殊情形。尾調用不必定是遞歸調用
(待增長……)
複製代碼
fun sayHi(name: String = "world", age: Int) {
...
}
👇
sayHi(age = 21)
在調用函數時,顯式地指定了參數 age 的名稱,這就是「命名參數」。
Kotlin 中的每個函數參數均可以做爲命名參數。
複製代碼
1 與命名參數相對的一個概念被稱爲「位置參數」,也就是按位置順序進行參數填寫。fun sayHi(name: String = "world", age: Int, isStudent: Boolean = true, isFat: Boolean = true, isTall: Boolean = true) {
...
}
調用 :sayHi(name = "wo", age = 21, isStudent = false, isFat = true, isTall = false)
2 若是函數混用位置參數與命名參數,那麼全部的位置參數都應該放在第一個命名參數以前fun sayHi(name: String = "world", age: Int) {
...
}
sayHi(name = "wo", 21) // IDE 會報錯,Mixing named and positioned arguments is not allowed
sayHi("wo", age = 21) // 這是正確的寫法複製代碼
val str: String? = "Hello"
👇
val length: Int = str?.length ?: -1
意思是若是左側表達式 str?.length 結果爲空,則返回右側的值 -1
複製代碼
Elvis 操做符還有另一種常見用法
工具
fun validate(user: User) {
val id = user.id ?: return // 👈 驗證 user.id 是否爲空,爲空時 return
}
// 等同於
fun validate(user: User) {
if (user.id == null) {
return
}
val id = user.id
}複製代碼
定義:帶上界和下界的通配符? 與類型上界不是一個東西 T extends Object
區別:?通配符上下界 一個是能不能讀我或能不能寫我, 類型上界只是限制類型範圍
不支持協變:子類的list泛型是不能賦值給父類list的泛型,引起一個類型擦除概念因爲有類型擦除存在,保證類型
的安全,java給泛型設置了這種限制
kotlin也有以上的限制 ,由此 引起出泛型通配符,解決了限制 達到協變
java:
List<? extends TextView> 返回的類型對象 能使用get相似的 但不能set值
List<? super Button> 返回的類型對象 不能使用get一類的 但能set值
kotlin裏面變成 :
List<out TextView> out表示 這個參數 只用來輸出,不用來輸入,只能讀我 不能寫我
List<in Button> in 表示 這個參數 只用來輸入,不用來輸出,只能寫我,不能讀我
還能夠用在泛型的類型參數上 interface Proucer<out T> {}
泛型的繼承 在kotlin 是 <T> where T : (一個以上繼承就須要where關鍵字)複製代碼
out
來支持協變,等同於 Java 中的上界通配符 ? extends
。in
來支持逆變,等同於 Java 中的下界通配符 ? super
。Kotlin的lambda表達式始終用花括號包圍,花括號中經過 箭頭(->)將實參和函數體分開,
post
lambda語法結構:
性能
{x:Int, y:Int -> x+y }
ui