Scala 同时支持不可变集合
和可变集合
两个主要的包
不可变集合:scala.collection.immutable
可变集合:scala.collection.mutable
Scala 默认采用不可变集合,对于几乎所有的集合类,Scala都同时提供了可变(mutable)和不可变(immutable)的版本
Scala 的集合有三大类:序列Seq、集Set、映射Map,所有的集合都扩展自Iterable特质,在Scala中集合有可变(mutable)和不可变(immutable)两种类型。
定长数组(声明泛型)
定义数组
这里的数组等同于Java中的数组,中括号的类型就是数组的类型
val arr1 = new Array[Int](10)
// 赋值,集合元素采用小括号访问
arr1(1) = 7
在定义数组时,直接赋值
// 使用 apply 方法创建数组对象
val arr1 = Array(1,2)
变长数组(声明泛型)
定长数组与变长数组的转换
arr1.toBuffer // 定长数组转可变数组
arr2.toArray // 可变数组转定长数组
多维数组
多维数组的定义和使用
定义
val arr = Array.ofDim[Double](3,4)
说明:二维数组中有三个一维数组,每个一维数组中有四个元素
赋值
arr(1)(1) = 11.11
Scala数组与Java的List的互转
Scala数组转Java的List
// Scala集合和Java集合互相转换
val arr = ArrayBuffer("1", "2", "3")
import scala.collection.JavaConversions.bufferAsJavaList
val javaArr = new ProcessBuilder(arr) //为什么可以这样使用?
val arrList = javaArr.command()
println(arrList) //输出 [1, 2, 3]
Java的List转Scala数组(mutable.Buffer)
import scala.collection.JavaConversions.asScalaBuffer
import scala.collection.mutable
// java.util.List ==> Buffer
val scalaArr: mutable.Buffer[String] = arrList
scalaArr.append("jack")
println(scalaArr)
元组也是可以理解为一个容器,可以存放各种相同或不同类型的数据。 说的简单点,就是将多个无关的数据封装为一个整体,称为元组, 最多的特点灵 活,对数据没有过多的约束。
注意:元组中最大只能有22个元素
val tuple1 = (1,2,3,"hello",4)
println(tuple1)
访问元组中的数据,可以采用顺序号(_顺序号),也可以通过索引 (productElement)访问。
object Tupleo1 {
def main(args: Array[String]): Unit = {
val t1 = (1, "a", "b", true, 2)
println(t1._1) //访问元组的第一个元素 ,从1开始
println(t1.productElement(0)) // 访问元组的第一个元素,从0开始
}
}
Tuple 是一个整体,遍历需要调其迭代器
// Scala可以将多个无关的数据封装为一个整体,称之为元组
var t1 = (1,"a","b",true,2)
// 循环元组,遍历元组
// tuple1是一个整体,遍历需要调其迭代器
for (item <- t1.productIterator){
println(item)
}
Scala中的List 和Java List 不一样,在Java中List是一个接口,真正存放数据是 ArrayList,而Scala的List可以直接存放数据,就是一个object,默认情况下 Scala的List是不可变的,List属于序列Seq。 val List = scala.collection.immutable.List object List extends
val list01 = List(1,2,3) // 创建时,直接分配元素
println(list01)
val list02 = Nil // 空集合
println(list02)
创建List的应用案例小结
val value1 = list1(1) // 1是索引,表示取出第2个元素
println(value1)
向列表中增加元素, 会返回新的列表/集合对象。注意:Scala中List元素的追加 形式非常独特,和Java不一样。
在列表的最后增加数据
var list1 = List(1, 2, 3, "abc")
// :+运算符表示在列表的最后增加数据
val list2 = list1 :+ 4
println(list1) //list1没有变化
println(list2) //新的列表结果是 [1, 2, 3, "abc",
在列表的最前面增加数据
var list1 = List(1, 2, 3, "abc")
// :+运算符表示在列表的最后增加数据
val list2 = 4 +: list1
println(list1) //list1没有变化
println(list2) //新的列表结果是?
在列表的最后增加数据
说明:
val list1 = List(1, 2, 3, "abc")
val list5 = 4 :: 5 :: 6 :: list1 :: Nil
println(list5)
//下面等价 4 :: 5 :: 6 :: list1
val list7 = 4 :: 5 :: 6 :: list1 ::: Nil
println(list7)
ListBuffer是可变的list集合,可以 添加,删除元素,ListBuffer属于序 列 //追一下继承关系即可 Seq var listBuffer = ListBuffer(1,2)
val lst0 = ListBuffer[Int](1, 2, 3)
println("lst0(2)=" + lst0(2))
for (item <- lst0) {
println("item=" + item)
}
val lst1 = new ListBuffer[Int]
lst1 += 4
lst1.append(5)
lst0 ++= lst1
val lst2 = lst0 ++ lst1
val lst3 = lst0 :+ 5
println("=====删除=======")
println("lst1=" + lst1)
lst1.remove(1)
for (item <- lst1) {
println("item=" + item)
}
队列的说明
import scala.collection.mutable
//说明: 这里的Int是泛型,表示q1队列只能存放Int类型
//如果希望q1可以存放其它类型,则使用 Any 即可。
val q1 = new mutable.Queue[Int]
println(q1)
向队列中追加单个元素和List
val q1 = new Queue[Int]
q1 += 20 // 底层?
println(q1)
q1 ++= List(2,4,6) //
println(q1)
//q1 += List(1,2,3) //泛型为Any才ok
println(q1)
//补充操作符重载... val cat = new Cat
println(cat.age)
cat += 9
println(cat.age)
class Cat {
var age: Int = 10
def +=(n:Int): Unit = {
this.age += n
println("xxx")
}
}
按照进入队列的顺序删除元素(队列先进先出)
q1.dequeue()
println(q1)
按照队列的算法,会将数据添加到队列的最后。
q1.enqueue(9, 8, 7)
println(q1)
返回队列的第一个元素
println(q1.head)
返回队列最后一个元素
println(q1.last)
返回队列的尾部
即:返回除了第一个以外剩余的元素, 可以级联使用,这个在递归时使用较多。
println(q1.tail)
println(q1.tail.tail)
HashMap 是一个散列表(数组+链表),它存储的内容是键值对(key-value)映射, Java中的HashMap是无序的,key不能重复。
public class TestJavaMap {
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);
System.out.println(hm);
System.out.println(hm.get("no2"));
}
}
构造不可变映射
Scala中的不可变Map是有序,构建Map中的元素底层是Tuple2类型。
val map1 = Map("Alice" -> 10, "Bob" -> 20, "Kotlin" -> "北京")
小结
构造可变映射
//需要指定可变Map的包
val map2 = scala.collection.mutable.Map("Alice" -> 10, "Bob" -> 20, "Kotlin" -> 30)
//说明
//1.从输出的结果看到,输出顺序和声明顺序不一致
创建空的映射
val map3 = new scala.collection.mutable.HashMap[String, Int]
println(map3)
对偶元组
即创建包含键值对的二元组, 和第一种方式等价,只是形式上不同而已。 对偶元组 就是只含有两个数据的元组。
val map4 = mutable.Map( ("A", 1), ("B", 2), ("C", 3),("D", 30) )
println("map4=" + map4)
println(map4("A"))
使用map(key)
val value1 = map2("Alice")
println(value1)
使用contains方法检查是否存在key
说明: 使用containts先判断在取值,可以防止异常,并加入相应的处理逻辑
val map4 = mutable.Map( ("A", 1), ("B", 2), ("C", 3),("D", 30.9) )
if( map4.contains("B") ) {
println("key存在 值= " + map4("B"))
} else {
println("key不存在")
}
使用map.get(key).get取值
通过 映射.get(键) 这样的调用返回一个Option对象,要么是Some,要么是None
var map4 = mutable.Map( ("A", 1), ("B", "北京"), ("C", 3) )
println(map4.get("A")) //Some
println(map4.get("A").get) //得到Some在取出
说明和小结:
使用map4.getOrElse()取值
getOrElse 方法 : def getOrElse[V1 >: V](key: K, default: => V1) 说明:
val map4 = mutable.Map( ("A", 1), ("B", "北京"), ("C", 3) )
println(map4.getOrElse("A","默认"))
更新map的元素
val map4 = mutable.Map( ("A", 1), ("B", "北京"), ("C", 3) )
map4("AA") = 20
println(map4)
添加map元素
增加单个元素
val map4 = mutable.Map(("A", 1), ("B","北京"), ("C", 3))
map4 += ( "D" -> 4 )
map4 += ( "B" -> 50 )
println(map4)
增加多个元素
val map4 = mutable.Map(("A", 1),("B","北京"),("C", 3))
val map5 = map4 + ("E"->1,"F"->3)
map4 += ("EE"->1,"FF"->3)
删除map元素
val map4 = mutable.Map(("A", 1),("B", "北京"),("C", 3))
map4 -= ("A", "B")
println("map4=" + map4)
说明
对map的元素(元组Tuple2对象 )进行遍历的方式很多,具体如下:
val map1 = mutable.Map( ("A", 1), ("B", "北京"), ("C", 3) )
for ((k, v) <- map1) println(k + " is mapped to " + v)
for (v <- map1.keys) println(v)
for (v <- map1.values) println(v)
for(v <- map1) println(v) //v是Tuple?
说明