目录
概述
集合是⼀种⽤来存储各种对象和数据的容器。
Scala
集合分为可变的和不可变的集合。
1.
不可变集合可以安全的并发访问。
2.
可变集合可以在适当的地⽅被更新或扩展。这意味着你可以修改,添加,移除⼀个集合的元素。
不可变集合,相⽐之下,永远不会改变。不过,你仍然可以模拟添加,移除或更新操作。但是这些操作将在每⼀种情况下都返回⼀个新的集合,同时使原来的集合不发⽣改变。
scala集合两个主要的包
#
不可变集合
scala.collection.immutable (Scala
默认采⽤不可变集合
)
#
可变集合
scala.collection.mutable
Scala的集合有三⼤类:序列
Seq
、集
Set
、映射
Map
,所有的集合都扩展⾃
Iterable
特质(暂理解为接⼝),意味着集合的基本特点是⽀持迭代遍历的。
分类
|
描述
|
Seq
|
序列。元素以线性⽅式存储,集合中可以存放重复对象,。参考
API文档
|
Set
|
集(数据集,区别于集合)。集中的对象不按特定的⽅式排序,并且没有重复对象。 参考 API文档
|
Map
|
⼀种把键对象和值对象映射的集合,它的每⼀个元素都包含⼀对键对象和值对象。 参考 API文档
|
不可变集合图
可变集合图
就说几个常用的吧
数组
数组元素内容要求类型⼀致。按照是否可扩容分为两种:
# Array
- 定⻓数组,数组不可扩容
scala.Array
# ArrayBuffer
- 变⻓数组,数组可扩容
scala.collection.mutable.ArrayBuffer
定⻓数组Array
Java中创建定⻓数组
int[] data = new int[3]; /*定义⻓度为3的数组*/
data[0] = 1; // 第⼀个元素
data[1] = 2; // 第⼆个元素
data[2] = 3; // 第三个元素
//也可以创建时初始化数组元素
int[] data=new int[]{1,2,3};
同样,Scala中也有两种创建⼀个定⻓数组的⽅式:
- 使⽤new关键字创建⼀个定⻓数组, var arr=new Array[Int](3)
- 直接使⽤Array创建并初始化⼀个数组,注意不再使⽤new关键字。 var arr=Array(1,2,3)
# 什么时候用new
如果没有提供object的apply方法时,class必须用new
定⻓数组是不可变集合吗?
不是。定⻓数组是可变集合的⼀种,内容可变,但是其⻓度不可变
。
# 为什么定⻓数组是可变集合?Array本身不属于 scala 集合成员,从前⾯类继承图中也可发现这⼀点,在可变集合图中 IndexedSeq 有⼀条虚线指 向了Array ,说明并不是直接继承关系。⼀般将Array 归为集合是因为 Scala 默认将 Array 隐式转换为 WrappedArray ,⽽ WrappedArray 实现了 IndexedSeq特质。从这⼀点上来说,String 与 WrappedString 也有异曲同⼯之妙,可以发现在不可变集合中, String 与 IndexedSeq也是虚线连接,也就是说在 Scala 中, String 可以当集合处理。参考下⽂中的描述,请⾃⾏通过源码验 证。
Array被隐式转换为WrappedArray(scala.collection.mutable.WrappedArray),间接拥有了集合的特征。
//Predef.scala 提示:所有scala⽂件默认导⼊Predef对象
implicit def genericWrapArray[T](xs: Array[T]): WrappedArray[T] =
if (xs eq null) null
else WrappedArray.make(xs)
变⻓数组ArrayBuffer
定义变⻓数组的⽅式
:
- val arr1=ArrayBuffer[Int]()
- val arr1=ArrayBuffer[Int](10)
使⽤ ArrayBuffer定义⻓度按需变化的数组。
import scala.collection.mutable.ArrayBuffer
object VarArrayDemo {
def main(args: Array[String]){
//定义⼀个空的可变⻓Int型数组
val nums = ArrayBuffer[Int]()
//在尾端添加元素
nums += 1
//在尾端添加多个元素
nums += (2,3,4,5)
//使⽤++=在尾端添加任何集合
nums ++= Array(6,7,8)
//这些操作符,有相应的 -= ,--=可以做数组的删减,⽤法同+=,++=
//使⽤append追加⼀个或者多个元素
nums.append(1)
nums.append(2,3)
//在下标2之前插⼊元素
nums.insert(2,20)
nums.insert(2,30,30)
//移除最后2元素
nums.trimEnd(2)
//移除最开始的⼀个或者多个元素
nums.trimStart(1)
//从下标2出移除⼀个或者多个元素
nums.remove(2)
nums.remove(2,2)
//使⽤增强for循环进⾏数组遍历
for(elem <- nums)
println(elem)
//基于下标访问使⽤增强for循环进⾏数组遍历
for(i <- 0 until nums.length)
println(nums(i))
}
}
执⾏结果:
定⻓数组与变⻓数组的转换
arr1.toBuffer //转为变⻓
arr2.toArray //转为定⻓
遍历数组
1.增强for循环,参⻅变⻓数组的代码
//使⽤增强for循环进⾏数组遍历
for(elem <- nums)
println(elem)
2.使⽤until⽣成脚标, 0 until 10 包含0但不包含10
//基于下标访问使⽤增强for循环进⾏数组遍历
for(i <- 0 until nums.length)
println(nums(i))
数组元素处理
#
现有数组包含元素
1-9
- 1.
对每个元素乘
2
后输出
- 2.
对每个偶数乘
2
后输出
分析:使⽤ yield 关键字将原始的数组进⾏转换会产⽣⼀个新的数组,原始的数组不变。也可以通过⾼阶函数filter 、 map 完成,这些⾼阶函数类似于 Java 中的 Lambda 表达式,很明显⾼阶函数更灵活,推荐使⽤⾼阶函数实现
object ArrayTransfer {
def main(args: Array[String]): Unit = {
//使⽤for推导式⽣成⼀个新的数组
val a = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)
val res1 = for(elem <- a) yield 2*elem
for(elem <- res1)
print(elem+" ")
println()
//对原数组元素过滤后⽣成⼀个新的数组
//将偶数取出乘以10后再⽣成⼀个新的数组
val res2 = for(elem <- a if elem%2 == 0)yield 2*elem
for(elem <- res2)
print(elem+" ")
println()
//使⽤filter和map转换出新的数组
val res3 = a.filter(_ % 2 == 0).map(2 * _)
for(elem <- res3)
print(elem+" ")
println()
}
执⾏结果:
数组常⽤⽅法
在Scala中,数组上的某些⽅法对数组进⾏相应的操作⾮常⽅便
object ArrayAlgorithm {
def main(args: Array[String]): Unit = {
val arr = Array(9,1,3,4,2,7,5,6,8)
println(arr.sum) // 数组求和:45
println(arr.max) // 数组求最⼤值:9
println(arr.min) // 数组求最⼩值:1
println(arr.sorted.toBuffer)// 数组排序:默认升序,返回⼀个新的数组
println(arr.sortWith(_<_).toBuffer)// 可以⾃定义排序规则,返回⼀个新的数组
}
}
//创建数组
//实例化了一个不可变的数组,类型为Int,长度为10
val array1 = new Array[Int](5)
//mkString()将一个集合中所有的元素拼接到一起
// -() = > 直接将所有的元素拼接到一起
// -(sep:String)=> 将所有的元素拼接到一起,中间指定的分隔符分隔
// -(start:String,ep:String,end:String)=> 将所有的元素拼接到一起,使用指定的分隔符分割,并指定的前缀和后缀
println(array1.mkString)
println(array1.mkString(","))
println(array1.mkString("[",",","]"))
00000
0,0,0,0,0
[0,0,0,0,0]
映射(Map)
在Scala
中,把哈希表这种数据结构叫做映射。
Scala
中的
Map
存储的内容是键值对
(key-value)
,
Map
区分可变
Map (scala.collection.mutable.Map) 和不可变
Map(scala.collection.immutable.Map)
。
不可变的
Map
(仅
TreeMap
) ⽀持有序,⽽可变的Map
是⽆序
的
构建映射
Map中的元素为⼆元组,可⽤两种⽅式表示。
("a",1)
"a"->1
//构建⼀个不可变的Map,默认即为不可变Map
//其中的元素其实是Tuple2
val scores = Map("zhangsan"->90,"lisi"->80,"wangwu"->70)
//使⽤元组⽅式构建
val scores = Map(("zhangsan",90),("lisi",80),("wangwu",70))
//构建⼀个可变的map,注意包名
val scores = scala.collection.mutable.Map(("zhangsan",90),("lisi",80),("wangwu",70))
访问映射中的值
根据键获取map中对应的值,可以有以下三种⽅法,推荐使⽤getOrElse⽅法。
//如果key存在,则返回对应的值
//如果key不存在,则抛出异常[java.util.NoSuchElementException]
//在Java中,如果key不存在则返回null
scala> val score1 = scores("lisi")
score1: Int = 80
//使⽤contains⽅法检查是否存在key对应的值
//使⽤containts先判断在取值,可以防⽌异常,并加⼊相应的处理逻辑
// 返回Boolean,true或者false
// 如果key存在,则返回true
// 如果key不存在,则返回false
map4.contains("B")
scala> val score2 = if(scores.contains("lisi")) scores("lisi") else 0
score2: Int = 80
//使⽤get⽅法取值,返回Option对象,Some或者None
//如果返回some,可以进⼀步通过get⽅法取回相应的值
//如果返回None,通过get⽅法取值,抛出异常 java.util.NoSuchElementException: None.get
var map4 = mutable.Map( ("A", 1), ("B", "北京"), ("C", 3) )
println(map4.get("A")) //Some
println(map4.get("A").get) //得到Some在取出
//使⽤getOrElse()取值
//def getOrElse[V1 >: V](key: K, default: => V1)
//如果key存在,返回key对应的值。
//如果key不存在,返回默认值。
scala> val score3 = scores.getOrElse("lisi",0)
score3: Int = 80
修改可变Map信息
遍历访问map
//修改键对应的值
//可变的map才能修改
//key存在,则修改对应的值,key不存在,则添加键值对
scala> scores("lisi") = 100
scala> scores
res23: scala.collection.mutable.Map[String,Int] = Map(lisi -> 100, zhangsan -> 90,wangwu -> 70)
scala> scores.update("lisi",50)
scala> scores
res25: scala.collection.mutable.Map[String,Int] = Map(lisi -> 50, zhangsan -> 90,wangwu -> 70)
//添加单个元素-⽅式1,如果key存在,则修改相应key的值。
scala> scores("zhaoliu") = 88
scala> scores
res27: scala.collection.mutable.Map[String,Int] = Map(lisi -> 50, zhangsan -> 90,zhaoliu -> 88, wangwu -> 70)
//添加单个元素-⽅式2
scala> scores +=("tom"->77)
res28: scores.type = Map(lisi -> 50, zhangsan -> 90, tom -> 77, zhaoliu -> 88, wangwu - > 70)
//添加多个元素-⽅式1
scala> scores = scores + ("tom"->77,"jerry"->88)
scala> scores +=("tom"->77,"jerry"->88)
res28: scores.type = Map(lisi -> 50, zhangsan -> 90, tom -> 77, zhaoliu -> 88, wangwu - > 7,jerry -> 88)
scala> val scores2 = Map(("za",90),("lq",80),("wg",70))
scores2: scala.collection.immutable.Map[String,Int] = Map(za -> 90, lq -> 80, wg -> 70)
//添加多个元素-⽅式2
scala> scores ++= scores2
res30: scores.type = Map(lisi -> 50, zhangsan -> 90, lq -> 80, tom -> 77, zhaoliu ->
88, za -> 90, wg -> 70, wangwu -> 70)
//移除键值对
scala> scores-"lisi"
res31: scala.collection.mutable.Map[String,Int] = Map(zhangsan -> 90, tom -> 77, lq -> 80, zhaoliu -> 88, za -> 90, wg -> 70, wangwu -> 70)
//移除多个键⼀
scala> scores--List("zhangsan","tom")
res33: scala.collection.mutable.Map[String,Int] = Map(lisi -> 50, lq -> 80, zhaoliu ->
88, za -> 90, wg -> 70, wangwu -> 70)
//移除多个键⼆
scala> scores-("lisi","lq")
res34: scala.collection.mutable.Map[String,Int] = Map(zhangsan -> 90, tom -> 77,
zhaoliu -> 88, za -> 90, wg -> 70, wangwu -> 70)
遍历map
//遍历
//返回⼀个set集合
scala> val res = scores.keySet
res: scala.collection.Set[String] = Set(lisi, zhangsan, lq, tom, zhaoliu, za, wg,wangwu)
scala> for(elem <- res)
| print(elem + " ")
lisi zhangsan lq tom zhaoliu za wg wangwu
//返回Map中所有key的迭代器
scala> val ite = scores.keys
ite: Iterable[String] = Set(lisi, zhangsan, lq, tom, zhaoliu, za, wg, wangwu)
scala> for (item <- ite)
| print(item + " ")
lisi zhangsan lq tom zhaoliu za wg wangwu
//返回Map中所有值的迭代器
scala> val values = scores.values
values: Iterable[Int] = HashMap(50, 90, 80, 77, 88, 90, 70, 70)
//返回键值对
scala> for (item <- scores)
| print(item+" ") (lisi,50) (zhangsan,90) (lq,80) (tom,77) (zhaoliu,88) (za,90) (wg,70) (wangwu,70)
//使⽤k、v表示⼆元组中的键和值
scala> for ((k,v) <- scores)
| print(k+":"+v+" ")
lisi:50 zhangsan:90 lq:80 tom:77 zhaoliu:88 za:90 wg:70 wangwu:70
HashMap
HashMap
是最常⽤的数据结构之⼀,查找和增删元素具有
O(1)
的时间复杂度。 同时
HashMap
也是默认的
Map
类型。
//可变Map
scala> var map4 = mutable.Map( ("A", 1), ("B", "北京"), ("C", 3) )
map4: scala.collection.mutable.Map[String,Any] = Map(A -> 1, C -> 3, B -> 北京)
scala> map4.getClass
res208: Class[_ <: scala.collection.mutable.Map[String,Any]] = class
scala.collection.mutable.HashMap
//不可变Map
scala> var map5 = Map( ("A", 1), ("B", "北京"), ("C", 3) ,("D",4),("E",5))
map5: scala.collection.immutable.Map[String,Any] = Map(E -> 5, A -> 1, B -> 北京, C -> 3, D -> 4)
scala> map5.getClass
res211: Class[_ <: scala.collection.immutable.Map[String,Any]] = class
scala.collection.immutable.HashMap$HashTrieMap
可变
HashMap
操作示例:
import scala.collection.mutable
object MutMapDemo extends App{
val map1 = new mutable.HashMap[String, Int]()
//向map中添加数据
map1("spark") = 1
map1 += (("hadoop", 2)) //注意外⾯括号,等价于map1.+=(("hadoop",2))
map1.put("storm", 3)
println(map1)
//从map中移除元素
map1 -= "spark"
map1.remove("hadoop")
println(map1)
}
TreeMap
返回按特定顺序排列的元素集合。
import scala.collection.immutable.TreeMap
var tm = TreeMap(3 -> 'x', 1 -> 'x', 4 -> 'x')
tm += (2 -> 'x')
tm //Map(1 -> x, 2 -> x, 3 -> x, 4 -> x)
列表(List)
Scala 列表类似于数组,它们所有元素的类型都相同,但是它们也有所不同:列表是不可变的,值⼀旦被定义了就不能改变,其次列表是链表结构,⽽数组不是。
1. 列表中的元素类型必须相同。2. 列表是有序的。3. 列表是不可变的,内容及⻓度都不可变。
List构造
注意:任何对List的修改操作都会返回新的List,⽽原List不会变化。
//空列表
//可以使⽤Nil构建⼀个空列表 Nil=List[Nothing]
val empty = Nil
//也可以使⽤空元素构建⼀个空列表
val empty : List[Nothing] = List()
scala> val fruit = List("apples", "oranges", "pears")
fruit: List[String] = List(apples, oranges, pears)
scala> val diag3 =
| List(
| List(1, 0, 0),
| List(0, 1, 0),
| List(0, 0, 1)
| )
diag3: List[List[Int]] = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1))
scala> val empty = List()
empty: List[Nothing] = List()
List的访问
scala> val nums = 1 :: 2 :: 3 :: 4 :: list0 :: Nil
nums: List[Any] = List(1, 2, 3, 4, List(5, 6))
scala> nums(1)
res22: Any = 2
scala> nums(3)
res23: Any = 4
List的遍历
/**
* List的各种遍历⽅式
*/
val lst = List(1,2,3,4,5);
print("foreach遍历:")
lst.foreach { x => print(x+",")} //foreach遍历,这个是传统遍历,新⼿不熟⽆奈之下可以⽤它
println("")
var temp = lst.map { x => x+1 } //遍历,与foreach的区别是返回值为List【B】
println("map遍历:"+temp.mkString(","));
var temp1 = lst.reduceLeft((sum,i)=>sum +i) //遍历,返回值类型是⼀个与集合相同的Int
println("reduce遍历返回Int:"+temp1);
var temp2 = lst.foldLeft(List[Int]())((x,y)=>y::x); //遍历,返回值是⾃定义类型
//ps fold类函数还可以改成 :\ ,/:的形式,代码精简了不少,但是可读性却减低了例如
println("foldLeft遍历返回⾃定义类型:"+temp2.mkString(","));
var temp3=( List[Int]() /: lst){(m,c)=>c::m} //遍历,实现反转
println("foldLeft遍历实现反转:"+temp2.mkString(","));
List的追加
object ImmutListDemo {
def main(args: Array[String]) {
//创建⼀个不可变的集合
val lst1 = List(1,2,3)
//将0插⼊到lst1的前⾯⽣成⼀个新的List ::和+:右结合
// ::为右结合操作符
// 将元素追加到集合开头
val lst2 = 0 :: lst1
val lst3 = lst1.::(0)
val lst4 = 0 +: lst1
val lst5 = lst1.+:(0)
//将⼀个元素添加到lst1的后⾯产⽣⼀个新的集合,:+左结合
val lst6 = lst1 :+ 3
val lst0 = List(4,5,6)
//将2个list合并成⼀个新的List
val lst7 = lst1 ++ lst0
//将lst1插⼊到lst0前⾯⽣成⼀个新的集合
val lst8 = lst1 ++: lst0
//将lst0插⼊到lst1前⾯⽣成⼀个新的集合
val lst9 = lst1.:::(lst0)
println(lst9)
}
}
List的基本操作
对列表的所有操作可以表达为⼀下三种
1.head 返回列表的第⼀个元素。
2.tail 返回除第⼀个元素之外所有元素组成的列表。
3.isEmpty 返回列表是否为空。
注意:其中
tail head
作⽤在空列表上,会报异常。
val list0 = List(1,2,3)
val list1 = List(4,5,6)
// head:返回列表第⼀个元素
list0.head // Int = 1
// tail:返回除了第⼀个元素之外的其他元素,以列表返回
list0.tail // List[Int] = List(2, 3)
// isEmpty:判断列表是否为空,为空时返回true
list0.isEmpty // Boolean = false
// concat:连接列表,返回⼀个新的集合
List.concat(list0,list1) // List[Int] = List(1, 2, 3, 4,5, 6)
// fill:使⽤数个相同的元素创建⼀个列表
List.fill(10)(2) // 重复次数:10,重复元素:2
// reverse:将列表顺序反转,返回⼀个新的集合
list0.reverse
//求列表⻓度
scala> List(1,2,3).length
res11: Int = 3
List的常⽤⽅法
//与head,tail对应的last init
scala> val abcde = List('a', 'b', 'c', 'd', 'e')
abcde: List[Char] = List(a, b, c, d, e)
scala> abcde.last
res12: Char = e
scala> abcde.init
res13: List[Char] = List(a, b, c, d)
//反转列表
scala> abcde.reverse
res14: List[Char] = List(e, d, c, b, a)
//tail,init的泛化
//提取列表的前n个元素
scala> abcde take 2
res15: List[Char] = List(a, b)
//丢弃列表的前n个元素
scala> abcde drop 2
res16: List[Char] = List(c, d, e)
scala> abcde splitAt 2
res17: (List[Char], List[Char]) = (List(a, b),List(c, d, e))
scala> List(abcde take 2, abcde drop 2)
res18: List[List[Char]] = List(List(a, b), List(c, d, e))
//拉链操作
scala> abcde zip List(1,2,3,4,5)
res22: List[(Char, Int)] = List((a,1), (b,2), (c,3), (d,4), (e,5))
List的模式拆分
列表可以使⽤模式匹配进⾏拆分。
scala> val fruit = List("apples", "oranges", "pears")
fruit: List[String] = List(apples, oranges, pears)
//给出的元素个数与列表的元素个数⼀致,否则会报错。
scala> val List(a, b, c) = fruit
a: String = apples
b: String = oranges
c: String = pears
//在元素个数不可知的情况下,最好使⽤::匹配。
scala> val a :: b :: rest = fruit
a: String = apples
b: String = oranges
rest: List[String] = List(pears)
//合并操作
scala> List(1, 2) ::: List(3, 4, 5)
res8: List[Int] = List(1, 2, 3, 4, 5)
scala> List(1, 2) ::: List(3, 4, 5) ::: List(6,7,8)
res9: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8)
scala> List(1, 2) ::: (List(3, 4, 5) ::: List(6,7,8))
res10: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8)
List的⾼阶⽅法
手累不写这个
可变列表ListBuffer
ListBuffer与List的区别在于:修改ListBuffer改变的是本身。
import scala.collection.mutable.ListBuffer
object MutListDemo extends App{
//构建⼀个可变列表,初始有3个元素1,2,3
val lst0 = ListBuffer[Int](1,2,3)
//创建⼀个空的可变列表
val lst1 = new ListBuffer[Int]
//向lst1中追加元素,注意:没有⽣成新的集合
lst1 += 4
lst1.append(5)
//将lst1中的元素最近到lst0中, 注意:没有⽣成新的集合
lst0 ++= lst1
//将lst0和lst1合并成⼀个新的ListBuffer 注意:⽣成了⼀个集合
val lst2= lst0 ++ lst1
//将元素追加到lst0的后⾯⽣成⼀个新的集合
val lst3 = lst0 :+ 5
}
Set
Set中的元素不可重复,⽆序(TreeSet除外)。
创建集合
不可变Set
import scala.collection.immutable.HashSet
val set0=Set(1,2,3,4,5)
println(set0.getClass) //scala.collection.immutable.HashSet
val set1 = new HashSet[Int]() //默认的Set
// 可以使⽤加号追加元素,会产⽣⼀个新的集合,原有set不变
val set2 = set1 + 1
// Set集合中不会出现重复的元素
val set3 = set2 ++ Set(1,2,3)
val set4 = Set(1,2,3,4,5,6)
// Set集合中的元素是⽆序的
print(set4)
// SortedSet中是有序的
val set5=scala.collection.immutable.TreeSet(1,1,10,5,6,7,8,11,13)
可变
Set
import scala.collection.mutable
object MutSetDemo extends App{
val mutableSet = Set(1,2,3)
println(mutableSet.getClass.getName) // scala.collection.mutable.HashSet
//创建⼀个可变的HashSet
val set1 = new mutable.HashSet[Int]()
//向HashSet中添加元素
set1 += 2
//add等价于+=
set1.add(4)
//删除⼀个元素,如果删除的对象不存在,则不⽣效,也不会报错
set1 -= 5
set1.remove(2)
println(set1)
}
集合基本操作
Scala集合有三个基本操作:
- head 返回集合第⼀个元素
- tail 返回⼀个集合,包含除了第⼀元素之外的其他元素
- isEmpty 在集合为空时返回true
对于Scala集合的任何操作都可以使⽤这三个基本操作来表达。实例如下:
object Test {
def main(args: Array[String]) {
val site = Set("1000phone", "Google", "Baidu")
val nums: Set[Int] = Set()
println( "第⼀⽹站是 : " + site.head )
println( "最后⼀个⽹站是 : " + site.tail )
println( "查看列表 site 是否为空 : " + site.isEmpty )
println( "查看 nums 是否为空 : " + nums.isEmpty )
}
}
查找集合中最⼤与最⼩元素
你可以使⽤
Set.min
⽅法来查找集合中的最⼩元素,使⽤
Set.max
⽅法查找集合中的最⼤元素。实例如下:
object Test {
def main(args: Array[String]) {
val num = Set(5,6,9,20,30,45)
//set集合遍历
for(x <- num) {
println(x)
}
// 查找集合中最⼤与最⼩元素
println( "Set(5,6,9,20,30,45) 集合中的最⼩元素是 : " + num.min )
println( "Set(5,6,9,20,30,45) 集合中的最⼤元素是 : " + num.max )
}
}
两个set之间的常⽤操作
你可以使⽤
++
运算符或
Set.++()
⽅法来连接两个集合。如果元素有重复的就会移除重复的元素。实例如下:
object Test {
def main(args: Array[String]) {
val site1 = Set("1000phone", "Google", "Baidu")
val site2 = Set("Faceboook", "Taobao")
// ++ 作为运算符使⽤
var site = site1 ++ site2
println( "site1 ++ site2 : " + site )
// ++ 作为⽅法使⽤
site = site1.++(site2)
println( "site1.++(site2) : " + site )
}
}
执⾏以上代码,输出结果为:
$ vim Test.scala$ scala Test.scalasite1 ++ site2 : Set(Faceboook, Taobao, Google, Baidu, 1000phone)site1.++(site2) : Set(Faceboook, Taobao, Google, Baidu, 1000phon)
交集
你可以使⽤ Set.& ⽅法或 Set.intersect ⽅法来查看两个集合的交集元素。实例如下:
object Test {
def main(args: Array[String]) {
val num1 = Set(5,6,9,20,30,45)
val num2 = Set(50,60,9,20,35,55)
// 交集
println( "num1.&(num2) : " + num1.&(num2) )
println( "num1.intersect(num2) : " + num1.intersect(num2) )
}
}
执⾏以上代码,输出结果为:
num1.&(num2) : Set(20, 9)
num1.intersect(num2) : Set(20, 9)
import scala.collection.immutable.HashSet
val set1 = Set(5,6,9,20,30,45)
val set2 = Set(50,60,9,20,35,55)
// contains:是否包含某⼀元素,包含返回true,不包含返回false
set1.contains(10)// Boolean = false
// &:交集运算
set1 & set2
set1.intersect(set2) // Set(20,9)
// &~:差集运算
set1 &~ set2
set1.diff(set2) // Set(5, 6, 45, 30)
// union:并集运算
set1.union(set2)
// scala.collection.immutable.Set[Int] = Set(5, 20, 6,
60, 9, 45, 35, 50, 55, 30)
// count:计算满⾜指定条件的集合元素个数
val fun = (x:Int) => x > 10
set1.count(fun) // Int = 3
// iterator:获得⼀个迭代器,可⽤于集合遍历
val it = set1.iterator
while(it.hasNext){
println(it.next())
}
// size:返回集合元素的数量
// splitAt:将集合拆分为两个容器,第⼀个由前n个元素组成,第⼆个由
剩下的元素组成
set1.splitAt(5)// 返回⼀个元组
// take:返回前n个元素
// takeRight:返回后n个元
// 可以使⽤to{type}快速转换为其他集合类型
集合的重要函数
package org.aurora.homework
object Test {
def main(args: Array[String]): Unit = {
val num1 = Set(5,6,9,20,30,45)
val num2= Set(50,60,9,20,35,55)
//交集 //Set(20, 9)
println(num1.intersect(num2))
//并集 //Set(5, 20, 6, 60, 9, 45, 35, 50, 55, 30)
println(num1.union(num2))
//差集 //Set(5, 6, 45, 30)
println(num1.diff(num2))
//1.Flatten 可以将存储在集合内部的集合压平
val list:List[List[Int]] = List(List(1,2,3),List(4,5,6),List(7,8,9))
val flatten: List[Int] = list.flatten
println(flatten)//List(1,2,3,4,5,6,7,8,9)
//forall 对集合中的元素条件进⾏过滤,只有当所有元素都满⾜要要求是,才会返回true 否则是false
val list1 = List(1,2,3,4,5)
val bool:Boolean = list1.forall(_ < 3)
println(bool) //false 需要所有的都小与3才true
//Partition 分区
//ps:Scala中只能模拟,Spark中是可以做到这个分区
//根据传⼊的函数 将是数据吸⼊到不同存储位置中
val list2 = List(1,2,3,4,5,6)
//返回值类型是⼀个元组
val tuple: (List[Int], List[Int]) = list2.partition(_%2 ==0)
println(tuple) //(List(2, 4, 6),List(1, 3, 5))
val list2_1 = tuple._1
val list2_2 = tuple._2
println(list2_1) //List(2, 4, 6)
println(list2_2) //List(1, 3, 5)
//2个聚合函数
//1. fold 求和 ⽐较特殊需要连个参数 ⼀个是默认值,另外⼀个是计算逻辑
// 当前fold是典型的 柯⾥化
val list3 = List(1,2,3,4,5)
//计算
//[A1 >: A](z: A1)(op: (A1, A1) => A1): A1
//现在属于是单线程,效果是看出来, 使⽤par的时候回出现多线程状态,
val sum = list3.fold(2)((res,n)=>res+n)
println(sum) // 17 求和
//fold有连个变种 foldleft 和 foldright
//2.reduce 直接求和 通过计算逻辑 进⾏集合中数据的计算
val list4 = List(1,2,3,4,5)
val sum2 = list4.reduce((x,y)=>x+y)
println(sum2)
//reduce也有两个变种 reduceleft 和 reduceright
}
}
并⾏集合
Scala
为了充分使⽤多核
CPU
,提供了并⾏集合(有别于前⾯的串⾏集合),⽤于多核环境的并⾏计算。
主要⽤到的算法有:
# Divide and conquer : 分治算法,Scala通过splitters,combiners等抽象层来实现,主要原理是将计算⼯作分解很多任务,分发给⼀些处理器去完成,并将它们处理结果合并返回
# Work stealin:算法,主要⽤于任务调度负载均衡(load-balancing),通俗点完成⾃⼰的所有任务之后,发 现其他⼈还有活没⼲完,主动(或被安排)帮他⼈⼀起⼲,这样达到尽早⼲完的⽬的
。