集合
什么是集合
集合是存储各种数据类型对象的一个容器
(1)是一个容器
(2)一般放同种数据类型的对象
(3)一般存放多个对象
集合
不可变集合:不可修改,但是可以模拟修改或删除等操作(可以对原集合进行插入,但原来的集合还保存)
可变集合:可修改,可以更新或者扩充
Traversable
Itarate扩展了Traversable集合对于遍历的算法
下方图:可变实现集合和不可变实现集合
下方图:不可变集合概括
下方图:可变集合
三大类:set 序列 map(有很多子类的实现,有一些可变子类的实现,还有一些不可变子类的实现)
数组
定长数组
数组的定义
scala> val a = Array[Int](2,3,4,5,5)
a: Array[Int] = Array(2, 3, 4, 5, 5)
scala> val b = new Array[Int](5)
b: Array[Int] = Array(0, 0, 0, 0, 0)
new方法中,必须声明数据类型,要不无法访问,出现下方图片错误
数组的访问
scala> a(0)
res9: Int = 2
scala> b(3)
res10: Int = 0
数组的常用方法
scala> a.sum
res3: Int = 19
scala> a.sum()
<console>:13: error: not enough arguments for method sum: (implicit num: Numeric[B])B.
Unspecified value parameter num.
a.sum()
^
sum、max、min、sorted方法都是无参数方法,因此不需括号
scala> a.max
res5: Int = 5
scala> a.min
res6: Int = 2
scala> a.sorted
res7: Array[Int] = Array(2, 3, 4, 5, 5)
scala> a.sorted.reverse
res8: Array[Int] = Array(5, 5, 4, 3, 2)
变长数组
变长数组的创建:
首先进行导
import scala.collection.mutable.ArrayBuffer,ArrayBuffer是个类,然后进行创建。
scala> var arr1 = ArrayBuffer[Int](1,2,3,4)
arr1: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4)
var arr2 = new ArrayBuffer(10)
arr2: scala.collection.mutable.ArrayBuffer[Nothing] = ArrayBuffer()
数组操作:
因为是变长数组,因此添加操作会很多
(1)操作符形式
scala> arr1 += (2,6)
res4: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 1, 2, 6)
scala> var arr3 = Array[Int](4,56)
arr3: Array[Int] = Array(4, 56)
scala> arr1 ++= arr3
res6: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 1, 2, 6, 4, 56)
相加操作++(addition)表示把两个traversable对象附加在一起或者把一个迭代器的所有元素添加到traversable对象的尾部。
(2)方法形式
scala> arr1.append(8)
scala> arr1
res8: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 1, 2, 6, 4, 56, 8)
scala> arr1.insert(0,111)
scala> arr1
res10: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(111, 1, 2, 3, 4, 1, 2, 6, 4, 56, 8)
insert的第一个参数代表插入的位置,第二个参数插入的值。详情请看scala官方API
https://www.scala-lang.org/api/current/scala/collection/mutable/ArrayBuffer.html
插入的位置越界,会出现错误
scala> arr1.length
res12: Int = 11
scala> arr1.insert(12,1000)
java.lang.IndexOutOfBoundsException: 12
at scala.collection.mutable.ArrayBuffer.insertAll(ArrayBuffer.scala:139)
at scala.collection.mutable.BufferLike$class.insert(BufferLike.scala:167)
at scala.collection.mutable.AbstractBuffer.insert(Buffer.scala:49)
... 32 elided
删除操作
scala> arr1 -= 8
res14: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(111, 1, 2, 3, 4, 1, 2, 6, 4, 56)
若数组中有两个一样的元素,删除第一个
scala> arr1 -= 1
res15: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(111, 2, 3, 4, 1, 2, 6, 4, 56)
从数组的后面删除两个
scala> arr1.trimEnd(2)
scala> arr1
res17: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(111, 2, 3, 4, 1, 2, 6)
remove删除位置0的2个元素
scala> arr1.remove(0,2)
scala> arr1
res19: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(3, 4, 1, 2, 6)
练习题:
给你一个数组,产生一新的数组,原有数组中的正数在新产生数组的前面,以原有数组的负数在新产生数组的后面,元素顺序保持不变。
scala> val al = Array(1,2,-6,-8,4,5,-2,33)
al: Array[Int] = Array(1, 2, -6, -8, 4, 5, -2, 33)
scala> val a2 = ArrayBuffer[Int]()
a2: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
scala> val a3 = ArrayBuffer[Int]()
a3: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
scala> for(i <- 0 to 7){
| if(al(i) < 0)
| {a3.append(al(i))}
| else{
| a2.append(al(i))}
| }
scala> for(e<-al){
| if(e>0) a2.append(e)
| else a3.append(e)
| }
scala> a2 ++= a3
res9: a2.type = ArrayBuffer(1, 2, 4, 5, 33, -6, -8, -2)
数组变换
yield、map、filter,不会改变原来数组元素
scala> for(e <- a) yield e*10
res12: Array[Int] = Array(10, 20, 30, 40, 50)
scala> a.map(_*10)
res13: Array[Int] = Array(10, 20, 30, 40, 50)
scala> a.map(x=>x*10)
res14: Array[Int] = Array(10, 20, 30, 40, 50)
scala> a.filter(_%2==0)
res15: Array[Int] = Array(2, 4)
scala> a.filter(x=>x%2==0)
res16: Array[Int] = Array(2, 4)
List
创建List
在首部添加
####创建不可变的List
scala> 0::list1
res1: List[Int] = List(0, 1, 2, 3)
scala> list1.::(0)
res4: List[Int] = List(0, 1, 2, 3)
scala> 0 +: list1
res5: List[Int] = List(0, 1, 2, 3)
scala> list1.+:(0)
res6: List[Int] = List(0, 1, 2, 3)
在尾部添加
scala> list1 :+ 4
res7: List[Int] = List(1, 2, 3, 4)
两个集合操作
scala> var list2 = List(4,5,6)
list2: List[Int] = List(4, 5, 6)
scala> list1 ++: list2
res8: List[Int] = List(1, 2, 3, 4, 5, 6)
####创建可变的List
scala> var list3 = ListBuffer(1,2,3)
list3: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3)
scala> list3 +=4
res9: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4)
scala> list3
res10: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4)
scala> list3.append(5)
scala> list3
res12: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4, 5)
scala> var list4 = new ListBuffer[Int]()
list4: scala.collection.mutable.ListBuffer[Int] = ListBuffer()
scala> list4.append(9)
scala> list4
res14: scala.collection.mutable.ListBuffer[Int] = ListBuffer(9)
scala> list3 ++ list4
res15: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4, 5, 9)
如下操作,并没有修改原来的列表,而是新建了列表
scala> list3 :+ 8
res19: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4, 5, 8)
scala> list3
res20: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4, 5)
列表转换
scala> list3.map(e=>e*10)
res25: scala.collection.mutable.ListBuffer[Int] = ListBuffer(10, 20, 30, 40, 50)
scala> list3.map(println("hello");_*10)//map中应该是函数,应该用{}。
<console>:1: error: ')' expected but ';' found.
list3.map(println("hello");_*10)
^
<console>:1: error: ';' expected but ')' found.
list3.map(println("hello");_*10)
^
//map中是函数,下面第一种方法:将整体看成一块个表达式,println(“hello'”)打印,而_*10作为函数传给map。第二种方法,讲println和e*10都看成函数传给map,吧list每一个元素做一个map,所以打印多次
scala> list3.map{println("hello");_*10}
hello
res26: scala.collection.mutable.ListBuffer[Int] = ListBuffer(10, 20, 30, 40, 50)
scala> list3.map{e=>println("Hello");e*10}
Hello
Hello
Hello
Hello
Hello
res28: scala.collection.mutable.ListBuffer[Int] = ListBuffer(10, 20, 30, 40, 50)
Map
创建Map:Map是一个容器,里面放着键值对
###创建map不可变的map
scala> val score = Map("zhangsan"->90,"lisi"->30)
score: scala.collection.immutable.Map[String,Int] = Map(zhangsan -> 90, lisi -> 30)
scala> val score = Map(("zhangsan",90),("list",30))
score: scala.collection.immutable.Map[String,Int] = Map(zhangsan -> 90, list -> 30)
scala>
scala> import scala.collection.mutable.Map
import scala.collection.mutable.Map
scala> val score = Map(("zhangsan",90),("list",30))
score: scala.collection.mutable.Map[String,Int] = Map(zhangsan -> 90, list -> 30)
scala> val score = Map("zhangsan"->90,"lisi"->30)
score: scala.collection.mutable.Map[String,Int] = Map(lisi -> 30, zhangsan -> 90)
基本操作
查询键值
scala> score("zhangsan")
res0: Int = 90
//如果查找的key不在map里,回报出异常,为了不报异常,选用下方方法
scala> score("zhang")
java.util.NoSuchElementException: key not found: zhang
at scala.collection.MapLike$class.default(MapLike.scala:228)
at scala.collection.AbstractMap.default(Map.scala:59)
at scala.collection.mutable.HashMap.apply(HashMap.scala:65)
... 32 elided
//首先我们想到的是if选择一下
scala> if(score.contains("zhang"))score("zhang")else -1
res2: Int = -1
scala> score.getOrElse("zhang",-2)
res3: Int = -2
//这是查询Map值的主要方法
scala> score.getOrElse("zhangsan",-2)
res4: Int = 90
当前Map是否为空
scala> score.isEmpty
res7: Boolean = false
返回当前集合所有键值和值
scala> score.keys
res9: Iterable[String] = Set(lisi, zhangsan)
scala> score.values
res10: Iterable[Int] = HashMap(30, 90)
其他操作
添加、修改
//发现原Map里没有,直接添加一个
scala> score("cch") = 100
//添加一个键值对
scala> score += ("jyh"->99)
res31: score.type = Map(lisi -> 30, cch -> 100, zhangsan -> 60, jyh -> 99)
//另一种添加键值对的方式,但必须加括号()
scala> score += ("jyh1",98)
<console>:14: error: type mismatch;
found : String("jyh1")
required: (String, Int)
score += ("jyh1",98)
^
<console>:14: error: type mismatch;
found : Int(98)
required: (String, Int)
score += ("jyh1",98)
^
scala> score += (("jyh1",98))
res33: score.type = Map(lisi -> 30, cch -> 100, zhangsan -> 60, jyh1 -> 98, jyh -> 99)
//删除无用的键值对
scala> score -= ("jyh1")
res37: score.type = Map(lisi -> 30, cch -> 101, zhangsan -> 60, jyh -> 99)
//遍历整个Map
scala> for((a,b)<-score)println(a+b)
lisi30
cch101
zhangsan60
jyh99
元组(不同数据类型对象的集合)
创建元组(三种方法)
scala> val t1 = (1,2,"java")
t1: (Int, Int, String) = (1,2,java)
scala> val t2,(a,b,c) = ("java","zs","bb")
t2: (String, String, String) = (java,zs,bb)
a: String = java
b: String = zs
c: String = bb
scala> val t3 = new Tuple5("java",2,3,4,4)
t3: (String, Int, Int, Int, Int) = (java,2,3,4,4)
不能修改元组里的元素值
scala> t3._2
res45: Int = 2
//就算t3中的元素用var修饰,元组里的元素也不能改变
<console>:13: error: reassignment to val
t3._2 = 1000
遍历元组
for((a,b)<-score)println(a+b)
lisi30
cch101
zhangsan60
jyh99
Set
特点:
set中的元素是不允许重复的;
set中的元素是无序的
创建set
scala> var jihe = Set(2,3,45)
jihe: scala.collection.immutable.Set[Int] = Set(2, 3, 45)
//因为jihe为不可变长元组,因此添加或者修改是新建了一个元组,而不是对原元组操作。
scala> jihe +"jfslj"
res53: scala.collection.immutable.Set[Any] = Set(java, 22, 44, jfslj, 55)
scala> jihe -"java"
res54: scala.collection.immutable.Set[Any] = Set(22, 44, 55)
//创建可变长数组,要不添加或删除没有对原元组造成影响
scala> import scala.collection.mutable.Set
import scala.collection.mutable.Set
scala> val set3 = Set("java",3,4)
set3: scala.collection.mutable.Set[Any] = Set(java, 3, 4)
其他操作
//获取头部信息
scala> set3.head
res0: Any = java
//获取除去头部剩余信息
scala> set3.tail
res1: scala.collection.mutable.Set[Any] = Set(3, 4)
//判别元组是否为空
scala> set3.isEmpty
res2: Boolean = false
scala> val set4 = Set(44,55,78)
set4: scala.collection.mutable.Set[Int] = Set(78, 55, 44)
//元组内部是数字的,求最大值最小值
scala> set4.max
res4: Int = 78
scala> set4.min
res5: Int = 44
//将两个元组合并(++),(+)代表向元组里添加元素
scala> set3 ++set4
res6: scala.collection.mutable.Set[Any] = Set(78, java, 3, 4, 55, 44)
//判断两个元组中重复的元素用方法intersect
scala> val set5 = Set(44,6,888889)
set5: scala.collection.mutable.Set[Int] = Set(888889, 6, 44)
scala> set4.intersect(set5)
res8: scala.collection.mutable.Set[Int] = Set(44)
集合函数
1.sum max min
scala> val list1 = List(2,3,4,56,6)
list1: List[Int] = List(2, 3, 4, 56, 6)
scala> list1.sum
res10: Int = 71
scala> list1.max
res11: Int = 56
scala> list1.min
res12: Int = 2
2.filter
//元素是否e满足被2整除
scala> list1.filter(e=>e%2==0)
res13: List[Int] = List(2, 4, 56, 6)
3.flatten:对集合中包含集合的集合做处理
scala> val list1 = List(2,3,4,56,6)
list1: List[Int] = List(2, 3, 4, 56, 6)
scala> var list2 = List(4,5,6)
list2: List[Int] = List(4, 5, 6)
scala> var list3 = List(list1,list2)
list3: List[List[Int]] = List(List(2, 3, 4, 56, 6), List(4, 5, 6))
scala> list3.flatten
res14: List[Int] = List(2, 3, 4, 56, 6, 4, 5, 6)
4.flatMap map
//map映射
scala> list1
res15: List[Int] = List(2, 3, 4, 56, 6)
scala> var map1 = list1.map(e=>e*10)
map1: List[Int] = List(20, 30, 40, 560, 60)
//将列表中的小写转换成大写,在进行flat
scala> val list5 = list4.map(e=>List(e,e.toUpper))
list5: List[List[Char]] = List(List(a, A), List(b, B), List(c, C))
scala> list5.flatten
res22: List[Char] = List(a, A, b, B, c, C)
//用flatmap方法将列表映射铺平
scala> list4.flatMap(e=>List(e,e.toUpper))
res20: List[Char] = List(a, A, b, B, c, C)
5.forall foreach
(forall 是对集合中的所有进行判断)
scala> list1
res23: List[Int] = List(2, 3, 4, 56, 6)
scala> list1.forall(e=>e>0)
res24: Boolean = true
scala> list1.forall(e=>e>5)
res25: Boolean = false
foreach对集合中的每一个元素进行操作
scala> list1.foreach(println)
2
3
4
56
6
6.foldLeft foldRight reduceLeft reduceRight
reduceLeft和reduceRight
下划线代表每一个元素,left代表从左开始进行加法运算,若要使减法,更改括号里面的符号。
scala> list1.reduceLeft(_+_)
res32: Int = 71
scala> list1.reduceLeft(-)
res33: Int = -67
scala> list1.reduceRight(-)
res34: Int = -47
foldLeft和foldRigth
在原有的基础上
scala>list1.foldLeft(10)(+)
res35:Int=81