1. 程式人生 > >基礎型別、運算子與表示式、流程控制、陣列與集合

基礎型別、運算子與表示式、流程控制、陣列與集合

該系列的博文是自己學習Kotlin的學習筆記整理,以備忘與回顧。整理來源 - 瘋狂Koltin講義

Kotlin預備知識

1、kotlin 是一門強型別語言;

2、kotlin-stdlib.jar是Kotlin執行時環境

Kotlin可以自由呼叫Java的各種庫,因此使用kotlin呼叫Android應用程式的Framework層開發應用程式甚至無序額外的學習,可以無縫的過渡到使用kotlin開發。

kotlinc (kotlin-jvm) -> Xxxx.class

kotlin-js -> js程式碼(前端或node.js程式碼都可以)

3、Kotlin程式與Java程式不同,Kotlin支援函數語言程式設計,且在Kotlin語言中,函式也是一等公民。因此函式可以獨立存在,即Kotlin程式只需要一個main函式作為程式入口,不需要將該main函式放在任何類中;

所謂"第一等公民"(first class),指的是函式與其他資料型別一樣,處於平等地位,可以賦值給其他變數,也可以作為引數,傳入另一個函式,或者作為別的函式的返回值。

舉例來說,下面程式碼中的print變數就是一個函式,可以作為另一個函式的引數。

var print = function(i){ console.log(i);};

  [1,2,3].forEach(print);

4、kotlinc(或kotlin-jvm)->XxxKt.class 或 Xxx.lass

kotlinxxxtlin檔案

基礎型別

1、與Java不同,Kotlin並不強制要求每條語句必須以分號結尾(前提是一行只有一條語句),如果一行有多條語句,則前面的語句需要使用分號表示結束。

2、kotlin中的[]不只可以訪問陣列,還可以訪問List和Map。

3、var 變數 val 常量;

var | val 變數名[:型別] [=初始值]

由於存在型別推斷,程式要麼通過":型別"的形式顯式指定該變數的型別,要麼為該變數指定初始值 - kotlin編譯器將會通過該初始值確定變數的型別,即var a:Int或var a=5,不能宣告變數時既不指定變數的型別,也不指定變數初始值。

使用val宣告的不可變變數其實相當於常量,意味著一旦初始化就不能再重新賦值。kotlin常量分為兩種:

  • 區域性範圍的常量:允許在宣告時不指定初始值,只要第一次使用之前指定初始值即可。

  • 類的常量屬性:既可以在宣告時指定初始值,也可以在類或結構體的構造器中指定初始值。

4、如果直接在Kotlin程式中定義變數、函式,kotlinc將會自動生成一個名為“檔名首字母大寫+Kt”的類,並將變數轉換為該類的靜態的getter和setter方法,函式則轉換為該類的靜態方法。

5、四種整型:Byte/Short/Int/Long  不支援八進位制

Kotlin的整型與Java的不同,Kotlin的整型是引用型別【大致相當於Java中的包裝類】,都繼承自Number型別。

Int -> int

Int? -> Integer 接收null值

比如:

var pm1 :Int = 200//相當於Java基本型別int

var pm2:Int = 200

pm1===pm2 true//基本型別比較,輸出true  

var pm3:Int?  =200//相當於Java包裝型別Integer

var pm4:Int? = 200

pm3===pm4  false//引用型別比較輸出false

兩種浮點型:Float和Double  十進位制和科學計數形式

如果宣告的變數初始值只是簡單的賦值為浮點值,則kotlin自動判斷該變數的型別為Double;

浮點型除以0.0會得到正無窮[正數/0.0]或負無窮大[負數/0.0]或非數[0.0/0.0 或 負數開方],整型除以0.0報錯。

注意:正無窮大都相等,負無窮大都相等,非數不與任意值相等;

6、Kotlin中的Char型就是簡簡單單的字元型,不能直接當成整型使用;即Char型值不能賦值給整型變數,整型值也不能賦值給Char型變數;

7、與Java程式不同,Kotlin不支援取值範圍小的資料型別隱式轉換為取值範圍大的型別

kotlin要求不同的整型的變數或值、Float與Double、浮點型與整型之間必須進行顯式轉換(toXXX),即缺乏隱式轉換

當進行型別轉換時,儘量向表數比較大的資料型別轉換,避免出現溢位。

8、雖然Kotlin缺乏隱式轉換,但是Kotlin在表示式中可以自動轉換,這是基於上下文推斷出來的,即當一個算術表示式中包含多個數值型值得時候,整個算術表示式得資料型別就會發生自動提升,其規則如下:

  • 所有得byte和short型別將被自動提升到Int型別;

  • 整個算術表示式得資料型別自動提升到與表示式中最高等級運算元同樣得型別,即以最高階運算元得資料型別為準

           Byte->Short-> Int -> Long -> Float ->Double

9、Char型值不能被當成整數進行算術運算,但Kotlin為char型別提供了加、減運算支援:

Char型加減一個整型值:用Char型值對應的字元編碼進行加減,運算結束在轉換為char;

兩個Char進行相減:用Char型值對應的字元編碼進行減運算,最後返回Int型別的值;

注意:兩個Char型值不能相加。

10、Any型別時Kotlin所有型別的父類,Any中只有三個方法:equals、hashcode、toString

11、Boolean -> boolean,Boolean? - >Boolean接收null值

12、null安全

kotlin語言對Java的重大改進之一,避免了空指標異常

var str = "fkstr"

var c: Int = str.toIntOrNull()//編譯不通過

var d: Int? = str.toIntOrNull()//編譯通過,d的值是null,因為轉換失敗了,如果str = "123",則會轉換成功。

kotlin對可空型別進行了限制:如果不加任何處理,可空型別不允許直接呼叫方法、訪問屬性。因此,通過可空型別與非可空型別的區分,Kotlin即可在程式中避免空指標異常。

var aStr: String = "a"

var bStr: String? = "b"

aStr = null//錯誤

bStr = null//正確

println(aStr.length)//正確

println(bStr.length)//錯誤

雖然,可空型別不允許直接呼叫方法、訪問屬性。但是可以先判斷該變數不為null,再呼叫該變數的方法和屬性。

var b:String? ="fk"

var len = if(b!=null)  b.length else -1

13、安全呼叫(?.)

user?.dog?.name

如果user不為null,則返回user的dog屬性,如果dog不為null,則返回dog的name屬性值,反過來,如果user或user.dog為null。則表示式也不會報空指標,整個表示式會返回null。

var str1: String? = "fkStr"

println(str1?.length)//5

str1 = null

println(str1?.length)//null

-->可為空的變數名 + ?.   就是安全呼叫

14、Elvis運算(?:)

如果?:左邊的表示式不為null,則返回左邊表示式的值,否則,返回?:右邊的表示式的值

var len = if(b!=null)  b.length else -1

var len = b?.length ?: -1;

由此可見,?:其實是if else分支的簡寫形式

15、強制呼叫(!!.)

不管是否是null,直接呼叫該變數的方法或屬性,這樣的呼叫可能會引發空指標異常

var b:String?="ss"

println(b!!.length)//2

b=null

println(b!!.length)//空指標異常

16、字串(String)/字串模板

可以通過str[i]這樣的方式訪問指定索引處的字元;通過for迴圈遍歷字串中的每一個字元

Kotlin的字串有兩種字面值:

  • 轉義字串:可以理解為Java中的字串

  • 原始字串:用三個引號引起來的部分都是字串內容,包括換行符等各種特殊字元,比如 """  |hahah  |heheheh  |aaaaa  """,可以通過trimMargin去除空格,預設使用|作為邊界符。也可以使用其他的作為邊界符,比如^,trimMargin("^"),"""  ^hahah  ^heheheh  ^aaaaa  """

注意:Kotlin中的String和Java中的String不是同一個類,因此提供的方法略有不同,但基本一致。可以說kotlin提供了更多的方法,比如toXxxx將字串轉換為數值:var a:String ="2.13" a.toDouble()等。

字串模板是允許在字串中嵌入變數和表示式,只需將變數和表示式放入到${}中即可。

println("${str}的長度是${str.length}")

17、typealias類型別名,在kotlin集合中使用的比較多;

typealias 類型別名 = 現有的型別

比如:typealias kotlin.ArrayList<E> = java.util.ArrayList<E>

運算子和表示式

kotlin基本支援Java的全部運算子,但不支援三目運算子(if可以代替);

kotlin的運算子都是以方法的形式來實現的,這些運算子都具有特定符號(如+ 或 * )和固定的優先順序。每種運算子對應的方法名都是固定的,因此我們可以通過運算子過載(operator)來實現任意兩個物件之間的運算。

1、== 相當於 java 的 equals,比較內容 ,   === 相當於 java的==,比較引用地址。比較運算子>,<,>=,<=基於CompareTo實現。

2、kotlin提供了與Java功能完全相同的位運算子,但這些位運算子都不是以特殊符給出的,而是以infix函式的形式給出的。kotlin的位運算子只能對Int和Long兩種資料型別起作用。

3、區間運算子

==>左邊界均不能大於右邊界,否則報錯

閉區間運算子:a..b,包含左右邊界值的區間,2..5   -> 2 3 4 5,如果a,b的值相等,則產生一個值只包含一個值的區間

半開區間運算子:a until b,用於定義一個從a~b(包括a邊界值,但不包括b邊界值),如果a,b的值相等,則是一個空區間

反向區間:a downTo b,此時要求b不能大於a,6 downTo 2

區間步長:step,比如for(num in 7 downTo 1 step 2)則輸出的值為1   3   5   7

4、運算子過載

kotlin的運算子都是靠特定名稱的方法支撐的,因此只要過載這些名稱的方法,我們就可以為任意類新增這些運算子。過載運算子的方法需要用operator修飾符進行標記。

data class Data(var v1: Int, var v2: Int) {

兩種方式:

a、普通方式

operator fun unaryPlus(): Data {

return Data(-v1, -v2)

}}

b、擴充套件函式方式

operator fun Data.unaryPlus():Data{

}

fun main(args: Array<String>) {

val d = Data(1,2)

println(-d)

}

流程控制

1、分支:if、when(替代Java的switch,功能更強大)

迴圈:while、do-while、for-in,拋棄了Java原有的普通的for迴圈。

if表示式:if分支還可以作為表示式使用,整個if表示式最終會返回一個值,因此if表示式可以取代Java的三目運算子

var age = 20

var ageStr = if (age > 20) "大於20歲" else if (age < 20) "小於20歲" else "等於20歲"

when分支語句:

var score = 20

when (score) {

10 -> {

println("10")

}

20 -> {

println("20")

}

else -> {

println("預設")

}}

相比較switch,when有三個小改進:

  • 可以匹配多個值;10,20->{......}
  • 分支後的值不再要求是常量,可以是任意表達式;str[0]-4,str[1]-4 ->{......}
  • 分支對條件表示式的型別沒有任何 要求;Date()->{......}

when表示式

when分支也可以作為表示式,符合條件的分支的程式碼塊的值就是整個表示式的值。

當when語句作為表示式使用時,when表示式也需要有一個返回值。

var score = 20

var str3 = when (score) {

10 -> {

println("10")

"10"

}

20 -> {

println("20")

"20"

}

else -> {

println("30")

"30"

}}

最終str3的值就是“20”

==>以下均為與表示式

when與in

var str = when(age){

in 10..25->{"花兒"}

...

else -> {

.....

}}

when與is

fun realPrice(price:Any)=when(price){

is String ->{}

...

else->{}

}

when與條件分支:用於取代if...else  if,此時不需要為when分支提供任何條件表示式,每個分支條件都是一個布林表示式,當指定分支的布林表示式為true,則執行該分支。

var in = readLine()

if(in!=null){

when{

in.matches(Regex("\\d+"))->{}//每個分支都是一個布林表示式

...

else->{}

}}

2、for-in

for(常量名 in 字串|範圍|集合)

說明:

a)for-in迴圈中的常量無需宣告。迴圈中的常量會在每次迴圈開始時自動被賦值。

b)可遍歷任何可迭代物件。

c)for-in迴圈的迴圈計數器相當於用val宣告的常量,因此不允許被重新賦值,即常量名再迴圈裡面是不允許開發者主動為其賦值

3、break與@標籤

除了具備常見的break用法之外,break與@標籤集合可以結束外層迴圈

//外層迴圈

[email protected] for (item in 0 until 20) {

//內層迴圈

for (item2 in 0..6) {

if (item2 == 2)

[email protected]

}}

當item2等於2的時候,整個迴圈就完全結束了

return結束一個方法:

fun test(){

for(i in 0 until 10){

if(i==2) return//當i==2的時候,整個方法就完全結束了

}}

陣列與集合

1、陣列Array<T>與集合【Kotlin為集合和陣列提供了大量的擴充套件方法,具體參照陣列,用法差不多】

Kotlin自己提供了一套集合體系,拋棄了Java集合體系中的Queue集合,但增加了可變集合和不可變集合的概念。Kotlin為陣列增加了一個Array類,為元素為基本資料型別的陣列增加了XxxxArray類。

Kotlin的集合由三種集合組成:

List、Set、Map

2、陣列

引用型別,Array<T>代表陣列,建立方式:

  • arrayOf()、arrayOfNulls()、emptyArray()等工具函式

  • Array(size:Int,init:(Int)->T)

arrayOfNulls<Double>(2)//建立指定長度、元素為null的陣列【元素均被初始化為null】,相當於Java中的動態陣列,由於無法推斷元素型別,因此需要使用泛型指定元素型別;

emptyArray()//建立長度為0的空陣列;

Array(5,{(it*26).toChar()})

此外,由於Array<T>要求它的元素必須是引用型別,因此,如果將基本型別的值存入Array<T>中,Kotlin將會完成自動裝箱操作。

for-in迴圈遍歷陣列或集合元素,不允許對迴圈變數進行賦值。對陣列使用for-in迴圈依然會被編譯成使用基於索引的迴圈,並不會建立迭代器進行遍歷,因此使用for-in迴圈陣列依然具有很好的效能。(Kotlin底層將其編譯成根據記憶體地址來訪問陣列元素)

更多知識點,參閱書籍

3、集合

Kotlin的集合類同樣由兩個介面派生:Collection和Map。Collection和Map是Java集合框架的根介面,這兩個介面又包含了一些子介面或實現類。

與Java集合不同,Java集合都是可變集合,但Kotlin的集合被分為:可變集合和不可變集合。只有可變集合才能進行增刪改操作,不可變集合只能進行讀操作。

Kotlin為Collection介面派生了一個子介面:MutableCollection,該介面又包含了兩個子介面:MutableSet和MutableList,代表了Kotlin的可變集合[可以理解為原有的Java集合]。而Collection直接派生的Set和List代表了不可變集合。

Set和MutableSet都有一個iterator()方法,但是普通的Set返回的iterator物件只包含hasNext和next兩個方法;而MutableSet的iterator方法除了包含hasNext和next之外,還包含了remove方法,用於遍歷的時候刪除元素。

注意:Kotlin只提供了HashSet、HashMap、LinkedHashMap、LinkedHashSet、ArrayList這5個集合,而且他們都是可變集合。如果開發者想使用其他集合,則依然可以使用Java集合框架所提供的類。

note:Kotlin在JVM平臺上並未真正實現HashSet、HashMap、LinkedHashMap、LinkedHashSet、ArrayList,只是為Java的HashSet、HashMap、LinkedHashMap、LinkedHashSet、ArrayList指定了一個類型別名而已,這樣就可以借用Java的這些集合類。

由於Kotlin並未真正實現任何集合類,它只是借用了Java集合框架原有的集合類,因此想要了解底層實現分析效能,直接看Java的就可以了。

Kotlin的不可變集合類並沒有暴露,我們只能通過函式來建立不可變集合。

Set集合都是無序的?錯誤!HashSet、HashMap是無序的,而LinkedHashMap、LinkedHashSet、TreeXxx都是有序的。

Kotlin規定以infix修飾的方法,能以運算子的方式進行呼叫。Set、Map等集合支援求並集、交集等方法均由infix修飾。

Set:

var data = setOf(1, 2, 3)//不可變,有序集合

var mutableData = mutableSetOf(1, 2, 3, 4)//可變,有序集合

var hashSetData = hashSetOf(1, 2, 4)//可變,無序集合

var linkedHashData = linkedSetOf(1, 2, 3)//可變,有序集合

var treeSetData = sortedSetOf(1, 2, 3)//可變,有序集合

Map:

var mapData = mutableMapOf("Java" to 90, "kotlin" to 88)//Kotlin使用to來指定key-value對,其中to之前的是key,之後的是value

println(mapData)//{Java = 90,Kotlin = 88}

for({key,value} in map)

for(en in map.entries)

for(keys in map.keys)

map.forEach({println("$(it.key)->${it.value}")})

相關推薦

JAVA基礎——初識JAVA(五)(流程控制分支語句迴圈語句特殊流程控制語句)

------------------------------------------------------------------------------------------------------------------

基礎型別運算子表示式流程控制陣列集合

該系列的博文是自己學習Kotlin的學習筆記整理,以備忘與回顧。整理來源 - 瘋狂Koltin講義 Kotlin預備知識 1、kotlin 是一門強型別語言; 2、kotlin-stdlib.jar是Kotlin執行時環境 Kotlin可以自由呼叫Java的各種庫,因

G筆記_Java基礎(變數基本型別運算子表示式-1)[案例]

JAVA Fundamental DAY02 1 變數使用常用錯誤彙總 1.1 問題 在我們使用變數的過程中,會遇到一些問題,在此將這些問題進行彙總,在今後使用的過程中,避免出錯。即使出現錯誤也可以很快的找到問題所在。 1.2 方案 變數在使用的過程中,常見問題總結為如下

【C#】— 基礎函式運算子表示式

從前人(學習完這個專案的人)那裡聽說傳智播客是北京最大計算機培訓班黑馬的前身,感覺對他的興趣又深了。只要對它有了興趣自然學的就會快了。看C#視訊有一段時間了,小楊老師講課很有意思,一點也不枯燥,幽默風趣還有一點點自戀哈哈哈,好像他快禿頂了。 對於C#視訊就像是我才來提高班學

【JAVA】基礎:註釋變數運算子流程控制函式

1、java的註釋 註釋:對程式的解釋說明,但是不參與程式的執行 單行註釋: // xxxxx 多行註釋: /* xxxxx */ 文件說明書:/**xxxxx */ 2、變數(資料型別) java把變數的型別分類兩類,第一類是我們的簡單資料(八大基本資料型別), 第二類是複雜資

c語言資料型別運算子表示式

資料型別   1.基本資料型別: 基本資料型別最主要的特點是,其值不可以分解為其他型別。也就是說,基本資料型別是 自我說明的 2.構造資料型別: 構造資料型別是根據已定於的一個或多個數據型別用構造的方法來定義的。也就是說, 一個構造型別的值可以分解為若干個“成員”或“元素

Python筆記——基本語法:識別符號資料型別變數運算子表示式/編碼風格

在Python 中,每行程式以換行符代表結束,如果一行程式太長的話,可以用“/”符號擴充套件到下一行。在python中以三引號(""")括起來的字串,列表,元組和字典都能跨行使用。並且以小括號(...)、中括號[...]和大括號{...}包圍的程式碼不用加“/”符也可擴充套件到多行。如:

C語言複習————基本資料型別運算子表示式

資料型別/運算子/表示式 主要分兩部分介紹,第一部分介紹常用的資料型別,例如:常量和變數/整型/實型/字元型;第二部分介紹算數運算子和算數表示式以及賦值運算子和逗號運算子。 一. 常用的資料型別 1. C語言中的資料型別 C語言中基本資料型別主要有整型/實型/字元型/字串型,本節主要介紹這幾種基本的資料型

python基礎流程控制數字和字符串處理

== python基礎 you else upper python3 統計 包含 文件 流程控制 條件判斷 if單分支:當一個“條件”成立時執行相應的操作。 語法結構: if 條件: command 流程圖: 示例:如果3大於2,那麽輸出字符串"very

Java第三天學習筆記~比較運算子&邏輯運算子程式的流程控制選擇結構迴圈結構

Java語言基礎 比較運算子&邏輯運算子----運算結果為true和false 邏輯運算子是連線兩個布林型別的表示式 &與;              |或;      &

運算子表示式

1.Python是什麼? Python 是一種解釋型語言 Python 是互動式語言 Python 是面嚮物件語言 Python 是初學者的語言 基於值的記憶體管理方式 如果為不同變數賦值為相同值,這個值在記憶體中只有一份,多個變數指向同一塊記憶體地址 2.

我的Python成長之路--Day48--mysql高階(檢視觸發器事物儲存過程函式流程控制資料備份恢復)

目錄 1、檢視 2、觸發器 3、事物 自定義函式 1、檢視 1.1、什麼是檢視 檢視是一張表或者多張表的查詢結果構成的一張虛擬表

自動化運維工具之Puppet變數正則表示式流程控制類和模板

  前文我們瞭解了puppet的file、exec、cron、notify這四種核心資源型別的使用以及資源見定義通知/訂閱關係,回顧請參考https://www.cnblogs.com/qiuhom-1874/p/14073437.html;今天我們來了解下puppet中的變數、正則表示式、流程控制、類和模板

flutter--Dart基礎語法(二)流程控制函式異常

一、前言 Flutter 是 Google 開源的 UI 工具包,幫助開發者通過一套程式碼庫高效構建多平臺精美應用,Flutter 開源、免費,擁有寬鬆的開源協議,支援移動、Web、桌面和嵌入式平臺。 Flutter是使用Dart語言開發的跨平臺移動UI框架,通過自建繪製引擎,能高效能、高保真地進行Andro

python全棧開發-Day2 布爾流程控制循環

class 用戶輸入 體重 命令 外部 表達 pan ger pre python全棧開發-Day2 布爾 流程控制 循環 一、布爾   1、概述 #布爾值,一個True一個False #計算機俗稱電腦,即我們編寫程序讓計算機運行時,應該是讓計算機無限接近人腦,或者說人

5月14日 python學習總結 視圖觸發器事務存儲過程函數流程控制索引

頻繁 表結構 可執行 開頭 好處 你在 get 16進制轉換 自帶 一、視圖 1、什麽是視圖 視圖就是通過查詢得到一張虛擬表,然後保存下來,下次用的直接使用即可 2、為什麽要用視圖 如果要頻繁使用一張虛擬表,可以不用重復查詢 3、如何用視圖 create vie

第二篇:流程控制數據類型字符編碼文件處理

span pan .html 列表 處理 數字類型 pytho python itl 第二篇:流程控制、數據類型、字符編碼、文件處理 PYTHON-流程控制之if/while/for PYTHON-流程控制之if/while/for-練習 PYTHON-基本數據

go語言初體驗(流程控制range遍歷函式結構體面向物件)

一、流程控制 // main package main import ( "fmt" ) func main() { x := 2 switch x { case 1: fmt.Print("beifeng 1") case 2:

go語言初體驗(流程控制range遍歷函數結構體面向對象)

需要 3.3 fmt float compute 捕獲異常 value 地址 異常處理 一、流程控制 // main package main import ( "fmt" ) func main() { x := 2 switch x {

流程控制陣列

1、switch語句 Java增強了switch語句的功能,允許switch語句的控制表示式是java.lang.String型別的變數或表示式,不能是StringBuffer或者StringBuilder這兩種字串型別。 總結:switch語句後的表示式資料型別只能是byte、shor