Scala的集合

目录

概述

数组

 定⻓数组Array

 变⻓数组ArrayBuffer

 定⻓数组与变⻓数组的转换

 遍历数组

 数组元素处理

数组常⽤⽅法

 映射(Map)

构建映射

访问映射中的值

修改可变Map信息

遍历访问map

遍历map

 HashMap

TreeMap

列表(List)

 List构造

 List的访问

 List的遍历

 List的追加

List的基本操作

List的常⽤⽅法

List的模式拆分

List的⾼阶⽅法

可变列表ListBuffer

Set

创建集合

集合基本操作

两个set之间的常⽤操作

交集

集合的重要函数

并⾏集合


概述

集合是⼀种⽤来存储各种对象和数据的容器。 Scala 集合分为可变的和不可变的集合。
1. 不可变集合可以安全的并发访问。
2. 可变集合可以在适当的地⽅被更新或扩展。这意味着你可以修改,添加,移除⼀个集合的元素。
不可变集合,相⽐之下,永远不会改变。不过,你仍然可以模拟添加,移除或更新操作。但是这些操作将在
每⼀种情况下都返回⼀个新的集合,同时使原来的集合不发⽣改变。

scala集合两个主要的包

# 不可变集合
scala.collection.immutable (Scala 默认采⽤不可变集合 )
# 可变集合
scala.collection.mutable
        Scala的集合有三⼤类:序列 Seq 、集 Set 、映射 Map ,所有的集合都扩展⾃ Iterable 特质(暂理解为接⼝),意味着集合的基本特点是⽀持迭代遍历的。

 

分类
描述
Seq
序列。元素以线性⽅式存储,集合中可以存放重复对象,。参考 API文档
Set
集(数据集,区别于集合)。集中的对象不按特定的⽅式排序,并且没有重复对象。 参考 API文档
Map
⼀种把键对象和值对象映射的集合,它的每⼀个元素都包含⼀对键对象和值对象。 参考 API文档
对于可变与不可变集合, Seq Set Map ⼜有不同的实现⽅式,下⼆图详细描述了其继承关系。官方文档
不可变集合图

可变集合图

 就说几个常用的吧

数组

数组元素内容要求类型⼀致。按照是否可扩容分为两种:
# 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被隐式转换为WrappedArrayscala.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

ListBufferList的区别在于:修改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.scala
site1 ++ 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通过splitterscombiners等抽象层来实现,主要原理是将计算⼯作分解很多任务,分发给⼀些处理器去完成,并将它们处理结果合并返回
# Work stealin:算法,主要⽤于任务调度负载均衡(load-balancing),通俗点完成⾃⼰的所有任务之后,发 现其他⼈还有活没⼲完,主动(或被安排)帮他⼈⼀起⼲,这样达到尽早⼲完的⽬的

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值