文章目录
数据结构
集合
-
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)
-
元组
Tuple-元组的基本使用
基本介绍
元组也是可以理解为一个容器,可以存放各种相同或不同类型的数据。 说的简单点,就是将多个无关的数据封装为一个整体,称为元组, 最多的特点灵 活,对数据没有过多的约束。
注意:元组中最大只能有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)
}
列表
创建List
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的应用案例小结
- List默认为不可变的集合
- List 在 scala包对象声明的,因此不需要引入其它包也可以使用
- val List = scala.collection.immutable.List
- List 中可以放任何数据类型,比如 arr1的类型为 List[Any]
- 如果希望得到一个空列表,可以使用Nil对象, 在 scala包对象声明的,因此不需 要引入其它包也可以使用 val Nil = scala.collection.immutable.Nil
访问List元素
val value1 = list1(1) // 1是索引,表示取出第2个元素
println(value1)
List-元素的追加
向列表中增加元素, 会返回新的列表/集合对象。注意: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
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)
}
队列
Queue-基本介绍
队列的说明
- 队列是一个有序列表,在底层可以用数组或是链表来实现。
- 其输入和输出要遵循先入先出的原则。即:先存入队列的数据,要先取出。 后存入的要后取出
- 在Scala中,由设计者直接给我们提供队列类型使用。
- 在scala中, 有 scala.collection.mutable.Queue 和 scala.collection.immutable.Queue , 一般来说,我们在开发中通常使用可变集合 中的队列。
队列的创建
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)
映射 Map
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介绍
- Scala中的Map 和Java类似,也是一个散列表,它存储的内容也是键值对 (key-value)映射,Scala中不可变的Map是有序的,可变的Map是无序的。
- Scala中,有可变Map (scala.collection.mutable.Map) 和 不可变 Map(scala.collection.immutable.Map)
构建Map
-
构造不可变映射
Scala中的不可变Map是有序,构建Map中的元素底层是Tuple2类型。
val map1 = Map("Alice" -> 10, "Bob" -> 20, "Kotlin" -> "北京")
小结
- 从输出的结果看到,输出顺序和声明顺序一致
- 构建Map集合中,集合中的元素其实是Tuple2类型
- 默认情况下(即没有引入其它包的情况下),Map是不可变map
- 为什么说Map中的元素是Tuple2 类型 [反编译或看对应的apply]
-
构造可变映射
//需要指定可变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-取值
-
使用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在取出
说明和小结:
- map.get方法会将数据进行包装
- 如果 map.get(key) key存在返回some,如果key不存在,则返回None
- 如果 map.get(key).get key存在,返回key对应的值,否则,抛出异常 java.util.NoSuchElementException:
-
使用map4.getOrElse()取值
getOrElse 方法 : def getOrElse[V1 >: V](key: K, default: => V1) 说明:
- 如果key存在,返回key对应的值。
- 如果key不存在,返回默认值。在java中底层有很多类似的操作。
val map4 = mutable.Map( ("A", 1), ("B", "北京"), ("C", 3) ) println(map4.getOrElse("A","默认"))
对map修改、添加和删除
更新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)
说明
- “A”,“B” 就是要删除的key, 可以写多个.
- 如果key存在,就删除,如果key不存在,也不会报错.
对map遍历
对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?
说明
- 每遍历一次,返回的元素是Tuple2
- 取出的时候,可以按照元组的方式来取