目錄
- 10.1、數據結構特點
- 10.2、不可變集合繼承層次一覽圖
- 10.3、可變集合繼承層次一覽圖
- 10.4、數組-定長數組(聲明泛型)
- 10.5、數組-變長數組(聲明泛型)
- 10.6、數組-Scala數組與Java的List的互轉
- 10.6.1、Scala數組轉Java的List
- 10.6.2、案例演示
- 10.6.3、補充了一個多態(使用trait來實現的參數多態)的知識點
- 10.6.4、Java的List轉Scala數組(mutable.Buffer)
- 10.7、元組Tuple-元組的基本使用
- 10.8、元組Tuple-元組數據的訪問
- 10.9、元組Tuple-元組數據的遍歷
- 10.10、列表List-創建List
- 10.11、列表List-訪問List元素
- 10.12、列表List-元素的追加
- 10.13、ListBuffer
- 10.14、隊列Queue-基本介紹
- 10.15、隊列Queue-隊列的創建
- 10.16、隊列Queue-隊列元素的追加數據
- 10.17、隊列Queue-刪除和加入隊列元素
- 10.18、隊列Queue-返回隊列的元素
- 10.19、映射Map-基本介紹
- 10.20、映射Map-構建Map
- 10.21、映射Map-構建Map
- 10.22、映射Map-取值
- 10.22.1、方式1-使用map(key)
- 10.22.2、方式2-使用contains方法檢查是否存在key
- 10.22.3、方式3-使用map.get(key).get取值
- 10.22.4、方式4-使用map4.getOrElse()取值
- 10.22.5、如何選擇取值的方式
- 10.23、映射Map-對map修改、添加和刪除
- 10.24、映射Map-對map遍歷
- 10.25、集Set-基本介紹
- 10.26、集Set-創建
- 10.27、集Set-可變集合的元素添加和刪除
- 10.28、集Set-更多操作
10.1、數據結構特點
10.1.1、Scala集合基本介紹
uml => 統一建模語言
1、Scala同時支持不可變集合和可變集合,不可變集合可以安全的併發訪問
兩個主要的包:
不可變集合:scala.collection.immutable
可變集合:scala.collection.mutable
2、Scala默認採用不可變集合,對於幾乎所有的集合類,Scala都同時提供了可變(mutable)和不可變(immutable)的版本
3、Scala的集合有三大類:序列Seq(有序的,LinearSeq)、集Set、映射Map【key->value】,所有的集合都擴展自Iterable特質,在Scala中集合有可變(mutable)和不可變(immutable)兩種類型。
什麼時候,應該使用什麼集合?
10.1.2、可變集合和不可變集合舉例
1、不可變集合:scala不可變集合,就是這個集合本身不能動態變化。(類似java的數組,是不可以動態增長的)
2、可變集合:可變集合,就是這個集合本身可以動態變化的。(比如:ArrayList,是可以動態增長的)
3、使用java做了一個簡單的案例說明
import java.util.ArrayList;
public class JavaCollection {
public static void main(String[] args) {
// 不可變集合類似java數組
int[] nums = new int[3];
nums[2] = 11;
nums[2] = 22;
// num[3] = 90 //?
String [] names = {"bi","sh"};
System.out.println(nums + " " + names);
// 可變集合舉例
ArrayList<String> a1 = new ArrayList<String>();
a1.add("zs");
a1.add("zs2");
System.out.println(a1 + "地址=" + a1.hashCode()); // 地址
a1.add("zs3");
System.out.println(a1 + "地址2=" + a1.hashCode());
}
}
10.2、不可變集合繼承層次一覽圖
10.2.1、圖
關於這個圖務必記住
10.2.2、小結
1.Set、Map是Java中也有的集合
2.Seq是Java沒有的,我們發現List歸屬到Seq了,因此這裏的List就和java不是同一個概念了
3.我們前面的for循環有一個1to3,就是IndexedSeq下的Vector
4.String也是屬於IndexeSeq
5.我們發現經典的數據結構比如Queue和Stack被歸屬到LinearSeq
6.大家注意Scala中的Map體系有一個SortedMap,說明Scala的Map可以支持排序
7.IndexSeq和LinearSeq的區別[IndexSeq是通過索引來查找和定位,因此速度快,比如String就是一個索引集合,通過索引即可定位][LineaSeq是線型的,即有頭尾的概念,這種數據結構一般是通過遍歷來查找,它的價值在於應用到一些具體的應用場景(電商網站,大數據推薦系統:最近瀏覽的10個商品)
10.3、可變集合繼承層次一覽圖
10.3.1、圖
10.3.2、對上圖的說明
1、在可變集合中比不可變集合更加豐富
2、在Seq集合中,增加了Buffer集合,將來開發中,我們常用的有ArrayBuffer和ListBuffer
3、如果涉及到線程安全可以選擇使用syn…開頭的集合
4、其它的說明參考不可變集合
10.4、數組-定長數組(聲明泛型)
10.4.1、第一種方式定義數組
說明
這裏的數組等同於Java中的數組,中括號的類型就是數組的類型
val arr1=new ArrayInt
//賦值,集合元素採用小括號訪問
arr1(1)=7
案例演示:
object ArrayDemo01 {
def main(args: Array[String]): Unit = {
//說明
// 1.創建了Array對象
// 2.[Int]表示泛型,即該數組中,只能存放Int
// 3.[Any]表示 該數組可以存放任意類型
// 4.在沒有賦值情況下,各個元素的值 0
// 5. arr01(3) = 10 表示修改第4個元素的值
val arr01 = new Array[Int](4) // 底層 Int [] arr01 = new int[4]
println(arr01.length) // 4
println("arr01(0)=" + arr01(0)) //0
// 數組的遍歷
for (i <- arr01) {
println(i)
}
println("===========================")
arr01(3) = 10 //
for (i <- arr01) {
println(i)
}
}
}
10.4.2、第二種方式定義數組
說明
在定義數組時,直接賦值
//使用apply方法創建數組對象
val arr1 = Array(1,2)
案例演示:
object ArrayDemo02 {
def main(args: Array[String]): Unit = {
// 說明
// 1. 使用的是 object Array 的 apply
// 2. 直接初始化數組,這時因爲你給了 整合和"" ,這個數組的泛型就是Any
// 3. 遍歷方式都一樣
var arr02 = Array(1, 2, "xxx")
arr02(1) = "xx"
for (i <- arr02) {
println(i)
}
// 可以使用我們傳統的方式遍歷, 使用下標的方式遍歷
for (index <- 0 until(arr02.length)){
printf("arr02[%d]=%s ",index,arr02(index)+"\t")
}
}
}
10.5、數組-變長數組(聲明泛型)
說明
/定義/聲明
va larr2= ArrayBufferInt
//追加值/元素
arr2.append(7)
//重新賦值
arr2(0)=7
代碼演示
import scala.collection.mutable.ArrayBuffer
object ArrayBufferDemo01 {
def main(args: Array[String]): Unit = {
// 創建ArrayBuffer
val arr01 = ArrayBuffer[Any](3, 2, 5)
// 通過下標訪問元素
println("arr01(1) = " + arr01(1)) // 2
// 遍歷
for (i <- arr01) {
println(i)
}
println(arr01.length) // 3
println("arr01.hash = " + arr01.hashCode())
// 使用append 追加數據,append支持可變參數
// 可以理解成Java的數組的擴容
arr01.append(90.0, 13) //
println("arr01.hash = " + arr01.hashCode())
println("==================")
arr01(1) = 89 // 修改
println("---------------------------------")
for (i <- arr01) {
println(i)
}
// 刪除,是根據下標刪除的
arr01.remove(0)
println("-------------------------------------")
for (i <- arr01) {
println(i)
}
println("最新的長度 = " + arr01.length)
}
}
10.5.1、變長數組分析小結
1.ArrayBuffer是變長數組,類似java的ArrayList
2.valarr2=ArrayBufferInt也是使用的apply方法構建對象
3.defappend(elems:A*){appendAll(elems)}接收的是可變參數.
4.每append一次,arr在底層會重新分配空間,進行擴容,arr2的內存地址會發生變化,也就成爲新的ArrayBuffer
10.5.2、定長數組與變長數組的轉換
說明
在開發中,我們可能使用對定長數組和變長數組,進行轉換
arr1.toBuffer //定長數組轉可變數組
arr2.toArray //可變數組轉定長數組
注意事項
arr2.toArray返回結果纔是一個定長數組,arr2本身沒有變化
arr1.toBuffer返回結果纔是一個可變數組,arr1本身沒有變化
代碼演示
import scala.collection.mutable.ArrayBuffer
object Array22ArrayBuffer {
def main(args: Array[String]): Unit = {
val arr2 = ArrayBuffer[Int]()
// 追加值
arr2.append(1, 2, 3)
println(arr2)
// 說明
//1. arr2.toArray 調用arr2的方法 toArray
// 2.將ArrayBuffer --> Array
// 3. arr2沒有任何的變化
val newarr = arr2.toArray
println(newarr)
// 說明
// 1.newarr.toBuffer 是把Array --> ArrayBuffer
// 2.底層的實現
/*
override def toBuffer[A1 >: A]: mutable.Buffer[A1] = {
val result = new mutable.ArrayBuffer[A1](size)
copyToBuffer(result)
result
}
*/
// 3.newarr本身沒有變化
val newArr2 = newarr.toBuffer
newArr2.append(123)
println(newArr2)
}
}
10.5.3、多維數組的定義和使用
說明
//定義
val arr=Array.ofDimDouble
//說明:二維數組中有三個一維數組,
每個一維數組中有四個元素
//賦值
arr(1)(1)=11.11
案例演示
object MultiplyArray {
def main(args: Array[String]): Unit = {
// 創建
val arr = Array.ofDim[Int](3,4)
// 遍歷
for (item <- arr ) { // 取出二位數組的各個元素(一維數組)
for (item2<-item){ // 元素(一維數組) 遍歷
print(item2 + "\t")
}
println()
}
// 指定取出
println(arr(1)(1)) // 0
// 修改值
arr(1)(1) = 100
println("--------------------------")
// 遍歷
for (item <- arr ) { // 取出二位數組的各個元素(一維數組)
for (item2<-item){ // 元素(一維數組) 遍歷
print(item2 + "\t")
}
println()
}
// 使用傳統下標進行遍歷
println("=======================")
for (i<-0 to arr.length -1){
for (j <- 0 to arr(i).length-1){
printf("arr[%d][%d]=%d\t",i,j,arr(i)(j))
}
println()
}
}
}
10.6、數組-Scala數組與Java的List的互轉
10.6.1、Scala數組轉Java的List
在項目開發中,有時我們需要將Scala數組轉成Java數組,看下面案例:
10.6.2、案例演示
import scala.collection.mutable.ArrayBuffer
object ArrayBuffer2JavaList {
def main(args: Array[String]): Unit = {
// Scala集合和Java集合的互轉
val arr = ArrayBuffer("1", "2", "3")
/*
implicit def bufferAsJavaList[A](b: mutable.Buffer[A]): ju.List[A] = b match {
case JListWrapper(wrapped) => wrapped
case _ => new MutableBufferWrapper(b)
}
*/
import scala.collection.JavaConversions.bufferAsJavaList
// 對象 ProcessBuilder, 因爲 這裏使用到上面的隱式函數 bufferAsJavaList
val javaArr = new ProcessBuilder(arr) // 爲什麼可以這樣使用
// 這裏arrList 就是java中的List
val arrList = javaArr.command()
println(arrList) // 輸出[1,2,3]
}
}
10.6.3、補充了一個多態(使用trait來實現的參數多態)的知識點
object MytraitDemo01 {
def main(args: Array[String]): Unit = {
val a01 = new A
B.test(a01)
}
}
trait Mytrait01 {}
class A extends Mytrait01 {}
object B {
def test(m: Mytrait01): Unit = {
println("b ··ok")
}
}
10.6.4、Java的List轉Scala數組(mutable.Buffer)
代碼實現
// java的List 轉成Scala的ArrayBuffer
// 說明
// 1.asScalaBuffer 是一個隱式函數
/*
implicit def asScalaBuffer[A](l: ju.List[A]): mutable.Buffer[A] = l match {
case MutableBufferWrapper(wrapped) => wrapped
case _ =>new JListWrapper(l)
}
*/
import scala.collection.JavaConversions.asScalaBuffer
import scala.collection.mutable
// java.util.List ==> Buffer
val scalaArr: mutable.Buffer[String] = arrList
scalaArr.append("jack")
scalaArr.append("tom")
scalaArr.remove(0)
println(scalaArr) // (2,3,jack.tom)
10.7、元組Tuple-元組的基本使用
10.7.1、基本介紹
元組也是可以理解爲一個容器,可以存放各種相同或不同類型的數據。
說的簡單點,就是將多個無關的數據封裝爲一個整體,稱爲元組,最多的特點靈活,對數據沒有過多的約束。
注意:元組中最大只能有22個元素
10.7.2、元組的創建
案例演示
//創建
// 1.tuple1 就是一個Tuple 類型是Tuple5
// 簡單說明:爲了高效操作元祖,編譯器根據元素的個數不同,對應不同的元祖類型
// 分別是Tuple -> Tuple22
//
val tuple1 = (1, 2, 3, "hello", 4)
println(tuple1)
對上述代碼的說明
1.t1的類型是Tuple5類是scala特有的類型
2.t1的類型取決於t1後面有多少個元素,有對應關係,比如4個元素=》Tuple4
3.給大家看一個Tuple5類的定義,大家就瞭然了
/*
final case classTuple5+T1,+T2,+T3,+T4,+T5
extendsProduct5[T1,T2,T3,T4,T5]
{
override deftoString()="("+_1+","+_2+","+_3+","+_4+","+_5+")"
}
*/
4.元組中最大只能有22個元素即Tuple1...Tuple22
10.8、元組Tuple-元組數據的訪問
10.8.1、基本介紹
訪問元組中的數據,可以採用順序號(_順序號),也可以通過索引(productElement)訪問。
10.8.2、應用案例
println("===============訪問元祖================")
val t1 = (1, "a", "b", true, 2)
println(t1._1) // 1 訪問元祖的第一個元素,從1開始
// 訪問元祖
println(t1.productElement(0)) //1 訪問元祖的第一個元素,從0開始
/*
override def productElement(n:Int)=nmatch{
case0=>_1
case1=>_2
case2=>_3
case3=>_4
case4=>_5
case_=>thrownewIndexOutOfBoundsException(n.toString())
}
*/
println(t1.productElement(0))//0//訪問元組的第一個元素,從0開始
10.9、元組Tuple-元組數據的遍歷
Tuple是一個整體,遍歷需要調其迭代器
// 遍歷元祖
println("===============遍歷元祖================")
// 元祖的遍歷需要使用迭代器
for (item <- t1.productIterator) {
println("item=" + item)
}
10.10、列表List-創建List
10.10.1、基本介紹
Scala中的List和JavaList不一樣,在Java中List是一個接口,真正存放數據是ArrayList,而Scala的List可以直接存放數據,就是一個object,默認情況下Scala的List是不可變的,List屬於序列Seq。
val List=scala.collection.immutable.List
object List extends SeqFactory[List]
10.10.2、創建List的應用案例
object ListDemo01 {
def main(args: Array[String]): Unit = {
// 說明
// 1.在默認情況下List,是Scala.collect.immutable.List,即不可變
// 2.在Scala中,List就是不可變的,如果需要可變的List,則使用ListBuffer
// 3.List 在 package object scala 做了
// val List = scala.collection.immutable.List
// 4.val Nil = scala.collection.immutable.Nil // List()
val list01 = List(1, 2, 3, "Hello") // 創建時,直接分配元素
println(list01)
val list02 = Nil // 空集合
println(list02)
}
}
10.10.3、創建List的應用案例小結
1、List默認爲不可變的集合
2、List在scala包對象聲明的,因此不需要引入其它包也可以使用val List=scala.collection.immutable.List
3、List中可以放任何數據類型,比如arr1的類型爲List[Any]
4、如果希望得到一個空列表,可以使用Nil對象,在scala包對象聲明的,因此不需要引入其它包也可以使用valNil=scala.collection.immutable.Nil
10.11、列表List-訪問List元素
// 訪問List的元素
val value1 = list01(1) // 1是索引,表示取出第二個元素,從0開始
println("value1=" + value1) // 2
10.12、列表List-元素的追加
10.12.1、基本介紹
向列表中增加元素,會返回新的列表/集合對象。注意:Scala中List元素的追加形式非常獨特,和Java不一樣。
10.12.2、方式2-在列表的最後增加數據
案例演示
println("=======給List追加元素後的效果=========")
// 通過 :+ 和 +: 給List追加元素(本身的集合並沒有變化)
var list1 = List(1, 2, 3, "abc")
// :+ 運算符表示在列表的最後增加數據
val list2 = list1 :+ 4 // (1,2,3,"abc",4)
println("list1=" + list1) // list沒有變化(1, 2, 3, "abc"),說明list1還是不可變的
println("list2=" + list2) // 新的列表結果是 [1,2,3,"abc",4]
val list3 = 10 +: list1 // (10,1, 2, 3, "abc")
println("list3=" + list3)
10.12.4、方式3-在列表的最後增加數據
說明:
1符號::表示向集合中新建集合添加元素。
2運算時,集合對象一定要放置在最右邊,
3運算規則,從右向左。
4:::運算符是將集合中的每一個元素加入到集合中去
應用案例
// :: 符號的使用 運算規則:從右向左
val list4 = List(1, 2, 3, "abc")
// 說明 val list5 = 4 :: 5 :: 6 :: list4 :: Nil 步驟
// 1.List()
// 2.List(list4(1,2,3,"abc"))
// 3.List(6list4(1,2,3,"abc"))
// 4.List(5,6list4(1,2,3,"abc"))
// 5.List(4,5,6list4(1,2,3,"abc"))
val list5 = 4 :: 5 :: 6 :: list4 :: Nil
println("list5=" + list5)
// 說明 val list6 = 4 :: 5 :: 6 :: list4 ::: Nil
// 1.List()
// 2.List(1,2,3,"abc")
// 3.List(6,1,2,3,"abc")
// 4.List(5,6,1,2,3,"abc")
// 5.List(4,5,6,1,2,3,"abc")
val list6 = 4 :: 5 :: 6 :: list4 ::: Nil
println("list6=" + list6)
10.12.5、課堂練習題
10.13、ListBuffer
10.13.1、基本介紹
ListBuffer是可變的list集合,可以添加,刪除元素,ListBuffer屬於序列
//追一下繼承關係即可
Seq var listBuffer=ListBuffer(1,2)
10.13.2、應用實例代碼
import scala.collection.mutable.ListBuffer
object ListBufferDemo01 {
def main(args: Array[String]): Unit = {
// 創建ListBuffer
val lst0 = ListBuffer[Int](1, 2, 3)
// 如何訪問
println("lst0(2)=" + lst0(2)) // 輸出 lst0(2)=3
for (item <- lst0) { // 遍歷,是有序的
println("item=" + item)
}
// 動態的增加元素,lst1 就會變化,增加一個一個的元素
val lst1 = new ListBuffer[Int] // 空的ListBuffer
lst1 += 4 // lst1 (4)
lst1.append(5) //lst1(4,5)
//
lst0 ++= lst1 // lst0 (1,2,3,4,5)
println("lst0="+lst0)
val lst2 = lst0 ++ lst1 // lst2(1,2,3,4,5,4,5)
println("lst2="+lst2)
val lst3 = lst0 :+ 5 // lst0 不變 lst3(1,2,3,4,5,5)
println("lst3="+lst3)
println("========刪除==========")
println("lst1=" + lst1)
lst1.remove(1) // 將下標爲1的元素刪除
for (item <- lst1) {
println("item=" + item) //4
}
}
}
10.14、隊列Queue-基本介紹
10.14.1、隊列的應用場景
10.14.2、隊列的說明
1.隊列是一個有序列表,在底層可以用數組或是鏈表來實現。
2.其輸入和輸出要遵循先入先出的原則。即:先存入隊列的數據,要先取出。後存入的要後取
3.在Scala中,由設計者直接給我們提供隊列類型Queue使用。
4.在scala中,有scala.collection.mutable.Queue和scala.collection.immutable.Queue,一般來說,
我們在開發中通常使用可變集合中的隊列
10.15、隊列Queue-隊列的創建
// 創建隊列
val q1 = new mutable.Queue[Int]
println(q1)
10.16、隊列Queue-隊列元素的追加數據
// 給隊列增加元素
q1 += 9
println("q1=" + q1) // 9
q1 ++= List(4, 5, 7) // 默認直接加在隊列後面
println("q1=" + q1) // (9,4,5,7)
//q1 += List(10,0) // 將List(10,0),作爲一個元素加入到隊列中,但要求類型是Any
10.17、隊列Queue-刪除和加入隊列元素
在隊列中,嚴格的遵守,入隊列的數據,放在隊位,出隊列的數據是隊列的頭部取出.
// dequeue 從隊列的頭部取出元素 q1本身會變化
val queueElement = q1.dequeue()
println("queueElement=" + queueElement + "\tq1=" + q1)
// enQueue 入隊列,默認是從隊列的尾部加入 .Redis
q1.enqueue(100,10,100,888)
println("q1=" + q1) // Queue(4,5,7,100,10,100,888)
10.18、隊列Queue-返回隊列的元素
println("==========返回隊列的元素============")
// 隊列 Queue 返回隊列的元素
// 1.獲取隊列的第一個元素
println(q1.head) // 4 ,對q1沒有任何影響
// 2.獲取隊列的最後一個元素
println(q1.last) // 888,對q1沒有任何影響
// 3.取出隊尾的數據,即:返回除了第一個意外剩餘的元素,可以級聯使用
println(q1.tail) // (5,7,100,10,100,888)
println(q1.tail.tail.tail.tail) // (10,100,888)
10.19、映射Map-基本介紹
10.19.1、Java中的Map回顧
HashMap是一個散列表(數組+鏈表),它存儲的內容是鍵值對(key-value)映射,Java中的HashMap是無序的,key不能重複。
案例演示
10.19.2、應用案例
import java.util.HashMap;
public class JavaHashMap {
public static void main(String[] args) {
HashMap<String,Integer> hm = new HashMap();
hm.put("no1",100);
hm.put("no2",200);
hm.put("no3",300);
hm.put("no4",400);
hm.put("no1",500); // 更新
System.out.println(hm); // 無序的
System.out.println(hm.get("no2"));
}
}
10.19.3、Scala中的Map介紹
1、Scala中的Map和Java類似,也是一個散列表,它存儲的內容也是鍵值對(key-value)映射,Scala中不可變的Map是有序的,可變的Map是無序的。
2、Scala中,有可變Map(scala.collection.mutable.Map)和不可變Map(scala.collection.immutable.Map)
10.20、映射Map-構建Map
10.20.1、方式1-構造不可變映射
Scala中的不可變Map是有序,構建Map中的元素底層是Tuple2類型。
代碼如下:
object MapDemo01 {
def main(args: Array[String]): Unit = {
//1.默認Map是immutable.Map
//2.key-value類型支持Any
//3.在Map的底層,每對key-value是Tuple2
val map1 = Map("Alice" -> 10, "Bob" -> 20, "Kotlin" -> "北京")
println(map1)
}
}
10.21、映射Map-構建Map
10.21.1、方式1-構造不可變映射
Scala中的不可變Map是有序,構建Map中的元素底層是Tuple2類型
// 方法1-構建不可變映射
// 1.默認Map是 immutable.Map
// 2.Key-Value 類型支持Any
// 3.在Map的底層,每對key-value是Tuple2
// 4.從輸出結果來看,輸出順序和聲明順序一致
val map1 = Map("Alice" -> 10, "Bob" -> 20, "Kotlin" -> "北京")
println(map1)
10.21.2、方式2-構造可變映射
// 方法2-構建可變映射
// 1.從輸出結果來看,輸出順序和聲明順序不一致
val map2 = mutable.Map("Alice" -> 10, "Bob" -> 20, "Kotlin" -> "北京")
map2.+=("a" -> 1)
println(map2)
10.21.3、方式3-創建空的映射
// 方法3-創建空的映射
val map3 = new mutable.HashMap[String, Int]
map3.+=("a" -> 1)
println("map3=" + map3)
10.21.4方式4-對偶元組
說明
即創建包含鍵值對的二元組,和第一種方式等價,只是形式上不同而已。
對偶元組就是隻含有兩個數據的元組。
案例演示
//方法4-對偶元祖
val map4 = mutable.Map(("Alice", 10), ("Bob", 20), ("Kotlin", "北京"))
println(map4)
10.22、映射Map-取值
10.22.1、方式1-使用map(key)
val value1=map2(“Alice”)
println(value1)
說明:
1)如果key存在,則返回對應的值
2)如果key不存在,則拋出異常[java.util.NoSuchElementException]
3)在Java中,如果key不存在則返回null
4)代碼
// 方式1-使用map(key)
println(map4("Alice")) // 10
//拋出異常 java.util.NoSuchElementException: key not found
// println(map4("Alice~"))
10.22.2、方式2-使用contains方法檢查是否存在key
//返回Boolean
//1.如果key存在,則返回true
//2.如果key不存在,則返回false
map4.contains(“B”)
說明
使用containts先判斷在取值,可以防止異常,並加入相應的處理邏輯
代碼
// 方式2-使用contains方法檢查是否存在key
if (map4.contains("Alice")) println("key存在,值=" + map4("Alice"))
else println("key不存在")
10.22.3、方式3-使用map.get(key).get取值
通過映射.get(鍵)這樣的調用返回一個Option對象,要麼是Some,要麼是None
說明和小結:
1)map.get方法會將數據進行包裝
2)如果map.get(key)key存在返回some,如果key不存在,則返回None
3)如果map.get(key).getkey存在,返回key對應的值,否則,拋出異常java.util.NoSuchElementException:None.get
案例演示
// 方法3-使用map.get(key).get取值
// 1.如果key存在 map.get(key) 就會返回Some(值).get,然後就可以取出
// 2.如果key不存在 map.get(key) 就會返回None
// some是Option的子類
println(map4.get("Alice").get)
// println(map4.get("Alice~").get)
// 拋出異常 java.util.NoSuchElementException: None.get
10.22.4、方式4-使用map4.getOrElse()取值
getOrElse方法:defgetOrElseV1>:V
說明:
1)如果key存在,返回key對應的值。
2)如果key不存在,返回默認值。在java中底層有很多類似的操作
3)代碼
//方法4-使用map.getOrElse()取值
println(map4.getOrElse("Alice~", "魚"))
10.22.5、如何選擇取值的方式
1)如果我們確定map有這個key,則應當使用map(key),速度快
2)如果我們不能確定map是否有key,而且有不同的業務邏輯,使用map.contains()先判斷在加入邏輯
3)如果只是簡單的希望得到一個值,使用map4.getOrElse(“ip”,“127.0.0.1”)
10.23、映射Map-對map修改、添加和刪除
10.23.1、更新map的元素
案例演示
val map5 = mutable.Map(("A", 1), ("B", "北京"), ("C", 3))
map5("AA") = 20 // 增加
map5("A") = 20 // 修改
println("map5 =" + map5)
小結
1)map是可變的,才能修改,否則報錯
2)如果key存在:則修改對應的值,key不存在,等價於添加一個key-val
10.23.2、添加map元素
說明:當增加一個key-value,如果key存在就是更新,如果不存在,這是添加
10.23.3、刪除map元素
案例演示
map5 -= ("A", "B") // -=底層做了包裝
println("map5 =" + map5)
說明
1)“A”,"B"就是要刪除的key,可以寫多個.
2)如果key存在,就刪除,如果key不存在,也不會報錯
10.24、映射Map-對map遍歷
對map的元素(元組Tuple2對象)進行遍歷的方式很多,具體如下
val map1=mutable.Map((“A”,1),(“B”,“北京”),(“C”,3))
for((k,v)<-map1)println(k+“ismappedto”+v)
for(v<-map1.keys)println(v)
for(v<-map1.values)println(v)
for(v<-map1)println(v)//v是Tuple?
說明
1.每遍歷一次,返回的元素是Tuple2
2.取出的時候,可以按照元組的方式來取
代碼如下:
// map的遍歷
val map6 = mutable.Map(("A", 1), ("B", "北京"), ("C", 3))
println("----(k, v) <- map6----")
for ((k, v) <- map6) println(k + "is mapped to" + v)
println("----v <- map6.keys----")
for (v <- map6.keys) println(v)
println("----v <- map6.values----")
for (v <- map6.values) println(v)
println("----v <- map6----")
// 這樣取出方式 v 類型時Tuple2
for (v <- map6) println(v + "key = "+v._1 + "val = "+v._2) // v是Tuple?
10.25、集Set-基本介紹
集是不重複元素的結合。集不保留順序,默認是以哈希集實現
10.25.1、Java中Set的回顧
java中,HashSet是實現Set接口的一個實體類,數據是以哈希表的形式存放的,裏面的不能包含重複數據。Set接口是一種不包含重複元素的collection,HashSet中的數據也是沒有順序的。
10.25.2、案例演示
Scala中Set的說明
import java.util.HashSet;
public class JavaHashSet {
public static void main(String[] args) {
HashSet hs = new HashSet<String>();
// Java中Set的元素 沒有順序 不能重複
hs.add("jack");
hs.add("tom");
hs.add("jack");
hs.add("jack2");
System.out.println(hs);
}
}
默認情況下,Scala使用的是不可變集合,如果你想使用可變集合,需要引用scala.collection.mutable.Set包
10.26、集Set-創建
import scala.collection.mutable
object SetDemo01 {
def main(args: Array[String]): Unit = {
val set = Set(1, 2, 3) // 不可變
println(set)
val set2 = mutable.Set(1, 2, "Hello") // 可變的
println("set2 = " + set2)
println(set.max)
println(set.min)
}
}
10.27、集Set-可變集合的元素添加和刪除
10.27.1、可變集合的元素添加
mutableSet.add(4)//方式1
mutableSet+=6//方式2
mutableSet.+=(5)//方式3
說明:如果添加的對象已經存在,則不會重複添加,也不會報錯
10.27.2、可變集合的元素刪除
val set02=mutable.Set(1,2,4,"abc")
set02-=2//操作符形式
set02.remove("abc")//方法的形式,scala的Set可以直接刪除值
println(set02)
//說明:如果刪除的對象不存在,則不生效,也不會報錯
10.27.3、set集合的遍歷操作
val set02=mutable.Set(1,2,4,"abc")
for(x<-set02){
println(x)
}