Kotlin初體驗(三)- 字串 和 容器
字串
字串與基本資料型別轉換
基本資料型別轉String,在上一篇部落格已經講過,呼叫toString(),反過來,字串又該如何轉換成基本資料型別呢?請看下錶
字串轉換為其他資料型別的Kotlin與Java方式對比
字串轉換目標 | Kotlin轉換方式 | Java轉換方式 |
---|---|---|
String->Int | toInt( ) | Integer.parseInt(字串變數) |
String->Long | toLong( ) | Long.parseLong(字串變數) |
String->Float | toFloat( ) | Float.parseFloat(字串變數) |
String->Double | toDouble( ) | Double.parseDouble(字串變數) |
String->Boolean | toBoolean( ) | Boolean.parseBoolean(字串變數) |
String->Char[ ] | toCharArray( ) | toCharArray( ) |
Kotlin方式更加簡單,直接“變數.toXXX( )”即可 。
字串常用方法
當然,轉換型別只是字串最基本方法,還有更多字串處理的其他方法,例如查詢子串,替換子串,擷取指定位置的子串,按照特定字元分割子串等。在這方面,Kotlin基本相容Java的相關方法。對於子串的查詢,二者都用indexOf( )
substring( )
,替換則為replace( )
,按照特定字元分割,二者都呼叫split ( )
。值得注意的是在這些方法中唯一不同的是,split的返回值,Java中split返回值是String[ ],Kotlin中,split方法返回值是String佇列,即List<String>
另外在Java中,獲取某個位置字元呼叫str.chatAt(index)
,Kotlin中直接可以str[index].toString( )
字串模板及其拼接
我們知道在Java中字串拼接,一般採用加號(+)強行拼接,或者String.format函式進行格式化。但是使用+ 容易和數值計算的+混淆,而後者格式化需要程式設計師牢記,如%d,%f,%s,%bd等格式轉換符,增加脫髮風險。而Kotlin恰如其分的對該痛點進行了優化,何必引入這些令人脫髮的轉換符呢?直接在字串中加入“$變數名”即可表示此處引用變數值,豈不妙哉! 直接上程式碼
val str: String = "Hello iblade"
var num: Int = 500
//拼接字串直接“str $變數名”,別忘了$前加一個空格
textView.text = "我拼接內容是 $str"
//另外先運算,再把運算結果拼接到字串的情況,可以直接加{ },當然AS會自動生成該括號
textView.text = "str length = ${str.length}"
//我想列印$怎麼辦?轉義字元 ${'XXX'} 其中,XXX會被原樣輸出。
textView.text = "美元結算為:${'$'}$num"
//如果只對單個字元做轉義的話,還有更簡單方式直接反斜槓 \X
textView.text = "美元結算為:\$$num"
字串拼接小結:
- 字串拼接用“$變數名”
- 單個字元轉義,反斜槓+字元 “ \X ”
- 多個字元轉義 “ ${ ’ XXX ’ } ”
容器
容器基本操作
與Java類似,Kotlin也擁有三種基本的容器,分別是集合Set,佇列List,對映Map,然後每種容器又分為只讀與可變兩種。這是為了判斷該容器,是否能進行增,刪,改等變更操作。Kotlin在對變數的修改操作很謹慎,每個變數在定義時就必須指定能否修改,比如新增val表示不能修改,只有var時才能修改。容器預設均為只讀容器,如需修改該容器,則需要加上Mutable
字首形成新的容器,如MutableList,MutableSet,MutableMap,只用可變容器才能增刪改。
Set,List,Map同屬於容器,當然也有一些共同方法,如下:
- isEmpty : 判斷該容器是否為空
- isNotEmpty : 判斷該容器是否非空
- clear :清空該容器
- contains : 判斷容器是否包含指定元素
- iterator : 獲取容器迭代器
- count : 獲取容器元素個數,也可以通過size屬性獲取
另外,Kotlin允許在宣告容器時進行賦值,就像陣列那樣,這是Java中無法做到的。 不同容器初始化賦值方法分別如下:
Kotlin的容器 | 容器名稱 | 初始化方法 |
---|---|---|
只讀集合 | Set | setOf |
只讀佇列 | List | listOf |
只讀對映 | Map | mapOf |
可變集合 | MutableSet | mutableSetOf |
可變佇列 | MutableList | mutableListOf |
可變對映 | MutableMap | mutableMapOf |
例如:
var season: List<String> = listOf("春", "夏", "秋", "冬")
var age: MutableList<String> = mutableListOf("1", "2", "3")
Set/MutableSet
特性:(對應Java中的Set)
- 元素無序儲存,無法通過下標訪問
- 元素唯一,不重複,hashcode校驗是否相同元素,重複則覆蓋
Set預設只讀,就不再展開講了。針對MutableSet研究一下; Mutable新增的元素,不知道具體位置,所以無法修改,可以用remove刪除指定元素。
三種遍歷
for-in迴圈、iterator,forEach for-in和iterator的用法與java一樣,都很簡單。重點說說forEach: 前兩種遍歷均脫胎於Java,程式碼書寫上不夠精煉,為了將程式碼精練到極致,Kotlin創造了forEach方法,明確指定該方法就是要依次遍歷容器內元素,forEach採用匿名函式形式,內部使用it代表每個元素。具體看程式碼
val topSchool: Set<String>
= setOf("清華大學", "北京大學", "河南工業大學", "河南大學", "南開大學")
//for-in
btnClick.setOnClickListener {
var temp = ""
//使用for-in語句取出容器中每條記錄
for (item in topSchool) {
temp = "$temp 校名:$item\n"
}
textView.text = "中國TOP${topSchool.size}名校排行榜:\n $temp"
}
//iterator
btnClick.setOnClickListener {
var temp = ""
val iterator = topSchool.iterator()
while (iterator.hasNext()) {
val item = iterator.next()
temp = "$temp 校名:$item\n"
}
textView.text = "中國TOP${topSchool.size}名校排行榜:\n $temp"
}
//forEach
btnClick.setOnClickListener {
var temp = ""
//forEach內部使用it代替每個元素
topSchool.forEach { temp = "$temp 校名:$it\n" }
textView.text = "中國TOP${topSchool.size}名校排行榜:\n $temp"
}
}
列印結果:
Set諸多不足,根本原因是無序,例如一旦新增,無法改值,不能根據位置找元素等。實際開發中,用到Set/MutableSet的機會還是挺少的。
List/MutableList:
list/MutableList 有序有下標,和Java中List一樣,使用頻率很高,常用方法有:get/set/add/removeAt
等;
遍歷
list的遍歷方法除了上述三種外,多了一種下標迴圈遍歷
val topUniversity: List<String> = listOf("清華大學", "北京人大學", "河南工業大學", "河南大學", "南開大學")
btnClick.setOnClickListener {
var desc = ""
//indices是佇列下標陣列
for (index in topUniversity.indices) {
val item = topUniversity[index]
desc = "$desc 校名:$item\n"
}
textView.text = "中國TOP${topUniversity.size}名校排行榜:\n $desc"
}
排序操作:sortBy / sortByDescending (升序/降序)
- reversed–相反順序;
- sorted–自然排序(升序);
- sortedBy–根據方法處理結果進行自然(升序)排序;
- sortedDescending–降序排序;
- sortedByDescending–根據方法處理結果進行降序排序;
val topUniversity: MutableList<String> = mutableListOf("清華大學", "MIT", "河南工業大學", "河南大學", "南開大學")
var sortAsc = true
btnClick.setOnClickListener {
if (sortAsc) {
topUniversity.sortBy { it.length }
} else {
topUniversity.sortByDescending { it.length }
}
var temp = ""
topUniversity.forEach { temp = "$temp 校名: $it\n" }
textView.text = "名牌大學TOP${topUniversity.size}按照\"${if (sortAsc) "升序" else "降序"}\"重新排名:\n$temp"
sortAsc = !sortAsc
}
**注意:**新版kotlin需要呼叫sorted()這樣帶"ed"字尾的方法才能返回List,而sort()是返回Unit。那麼這兩種方法還有哪些區別,或者說分別在什麼場景下使用?
還是以sort為例,sorted()處理過程中會新建臨時的List來儲存結果資料,對原來的呼叫者List不會做任何改變,所以需要將新建的物件返回;而sort()是在原來的List基礎上進行元素順序的調整,不會新建物件,所以不需要返回List。
總數操作
方法作用:
-
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–獲取方法處理後返回結果值的總和;
過濾操作:
-
drop–返回去掉前n個元素後的列表;
-
dropWhile–返回從第一項起,去掉滿足條件的元素,直到不滿足條件的一項為止;
-
dropLastWhile–返回從最後一項起,去掉滿足條件的元素,直到不滿足條件的一項為止;
-
filter–過濾掉所有不滿足條件的元素;
-
filterNot–過濾掉所有滿足條件的元素;
-
filterNotNull–過濾掉所有值為null的元素;
-
slice–過濾掉非指定下標的元素,即保留下標對應的元素過濾List中指定下標的元素(比如這裡只保留下標為1,3,4的元素),當過濾list中有元素值大於目標List大小時會出現異常;
-
take–返回從第一個開始的n個元素;
-
takeLast–返回從最後一個開始的n個元素;
-
takeWhile–返回不滿足條件的下標前面的所有元素的集合;
對映操作:
方法作用:
-
flatMap–合併兩個集合,可以在合併的時候對迭代元素值it多想要的操作;
-
groupBy–將集合中的元素按照某個條件分組,返回Map;
-
map–將集合中的元素通過某個方法轉換後的結果存到一個集合中;
-
mapIndexed–除了得到轉換後的結果,還可以拿到index(下標);
-
mapNotNull–執行方法轉換前過濾掉為null的元素;
元素操作:
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;
可以看到,容易出現異常的操作Kotlin會給出另一個安全呼叫的替代,如first與firstOrNull。
生產操作:
方法作用:
-
partition–根據判斷條件是否成立,拆分成兩個Pair;
-
plus–合併兩個List,可以用"+"替代;
-
zip–兩個集合按照下標組合成一個個的Pair塞到集合中返回;
-
unzip–將包含多個Pair的List轉換成含List的Pair;
-
Pair物件的資料組成形式為(first, secord),即Pair(1, 2).first可以取出資料1。
注意:文件和網上一些老的資料還提到了merge操作,編碼時提示找不到符號,查資料發現從Kotlin 1.0 Beta 2後的版本開始就棄用了。
Map/MutableMap:
map與Java中類似: containsKey / containsVaule 用於判斷是否包含鍵或值 初始化賦值時,鍵值對有兩種方式:“鍵名 to 鍵值” 和 “Pair(鍵名,鍵值)” 遍歷三種形式類似,需要說明一點是,forEach需要不低於API 24以上版本才支援: