目錄
類型
不可變集合
可變集合
數(shù)組
不可變
可變數(shù)組
不可變數(shù)組與可變數(shù)組的轉(zhuǎn)換
多維數(shù)組
List
list運(yùn)算符
可變 ListBuffer
Set 集合
不可變 Set
可變 mutable.Set
Map 集合
可變 Map
元組
操作
通用操作
衍生集合操作
計(jì)算函數(shù)
排序
sorted
sortBy
sortWith
計(jì)算高級(jí)函數(shù)
實(shí)例
WordCount 案例
復(fù)雜案例
隊(duì)列
并行集合
來(lái)源:
類型
不可變集合:scala.collection.immutable
可變集合: scala.collection.mutable
不可變集合
可變集合

IndexedSeq 和 LinearSeq 的區(qū)別:
IndexedSeq 是通過(guò)索引來(lái)查找和定位,因此速度快,比如 String 就是一個(gè)索引集合,通過(guò)索引即可定位
LinearSeq 是線型的,即有頭尾的概念,這種數(shù)據(jù)結(jié)構(gòu)一般是通過(guò)遍歷來(lái)查找?
數(shù)組
不可變
val arr =new Array[類型](大小)
val arr01 = new Array[Int](4)
println(arr01.length) // 4
//(2)數(shù)組賦值
//(2.1)修改某個(gè)元素的值
arr01(3) = 10
//(2.2)采用方法的形式給數(shù)組賦值
arr01.update(0, 1) //將第0個(gè)數(shù)賦值為1
//(3)遍歷數(shù)組
//(3.1)查看數(shù)組
println(arr01.mkString(","))
//(3.2)普通遍歷
for (i <- arr01) {
println(i)
}
//(3.3)簡(jiǎn)化遍歷
def printx(elem: Int): Unit = {
println(elem)
}
arr01.foreach(printx)
// arr01.foreach((x)=>{println(x)})
// arr01.foreach(println(_))
arr01.foreach(println)
//(4)增加元素(由于創(chuàng)建的是不可變數(shù)組,增加元素,其實(shí)是產(chǎn)生新的數(shù)組)
println(arr01)
val ints: Array[Int] = arr01 :+ 5 //末尾追加
val ints1: Array[Int] = arr01 +: 5 //頭部追加
println(ints)
//如果使用空格 替換掉 “.” 的時(shí)候,如果后面的操作符是以":" 號(hào)結(jié)尾的,那操作符是從右邊往左邊的
val new = Arr :+ 15
val new1 = 15 +: Arr
// 19 +: 32 +: Arr
第二種方式定義數(shù)組
val arr1 = Array (1, 2)
(1)在定義數(shù)組時(shí),直接賦初始值
(2)使用 apply 方法創(chuàng)建數(shù)組對(duì)象
object TestArray {
def main(args: Array[String]): Unit = {
var arr02 = Array(1, 3, "bobo")
println(arr02.length)
for (i <- arr02) {
println(i)
}
}
}
可變數(shù)組
import scala.collection.mutable.ArrayBuffer
val arr01 = ArrayBuffer[Any](3, 2, 5)
//(1)創(chuàng)建并初始賦值可變數(shù)組
val arr01 = ArrayBuffer[Any](1, 2, 3)
//(2)遍歷數(shù)組
for (i <- arr01) {
println(i)
}
println(arr01.length) // 3
println("arr01.hash=" + arr01.hashCode())
//(3)增加元素
//(3.1)追加數(shù)據(jù)
arr01.+=(4)
arr01.foreach(print(_ ))
println()
//(3.2)向數(shù)組最后追加數(shù)據(jù)
arr01.append(5,6)//追加 5,6
arr01.foreach(print(_))
//(3.3)向指定的位置插入數(shù)據(jù)
arr01.insert(0,7,8) //第0個(gè)位置 插入 7,8
arr01.foreach(print(_))
println()
println("arr01.hash=" + arr01.hashCode())
//(4)修改元素
arr01(1) = 9 //修改第 2 個(gè)元素的值
println("--------------------------")
for (i <- arr01) {
println(i)
}
println(arr01.length) // 5
不可變數(shù)組與可變數(shù)組的轉(zhuǎn)換
arr1.toBuffer //不可變數(shù)組轉(zhuǎn)可變數(shù)組
arr2.toArray //可變數(shù)組轉(zhuǎn)不可變數(shù)組
(1)arr2.toArray 返回結(jié)果才是一個(gè)不可變數(shù)組,arr2 本身沒(méi)有變化
(2)arr1.toBuffer 返回結(jié)果才是一個(gè)可變數(shù)組,arr1 本身沒(méi)有變化
多維數(shù)組
val arr = Array.ofDim[Double](3,4)
說(shuō)明:二維數(shù)組中有三個(gè)一維數(shù)組,每個(gè)一維數(shù)組中有四個(gè)元素
object DimArray {
def main(args: Array[String]): Unit = {
//(1)創(chuàng)建了一個(gè)二維數(shù)組, 有三個(gè)元素,每個(gè)元素是,含有 4 個(gè)元素一維
數(shù)組()
val arr = Array.ofDim[Int](3, 4)
arr(1)(2) = 88
//(2)遍歷二維數(shù)組
for (i <- arr) { //i 就是一維數(shù)組
for (j <- i) {
print(j + " ")
}
println()
}
}
}
List
object TestList {
def main(args: Array[String]): Unit = {
//(1)List 默認(rèn)為不可變集合
//(2)創(chuàng)建一個(gè) List(數(shù)據(jù)有順序,可重復(fù))
val list: List[Int] = List(1,2,3,4,3)
//(7)空集合 Nil
val list5 = 1::2::3::4::Nil
//(4)List 增加數(shù)據(jù)
//(4.1)::的運(yùn)算規(guī)則從右向左
//val list1 = 5::list
val list1 = 7::6::5::list
//(4.2)添加到第一個(gè)元素位置
val list2 = list.+:(5)
//(5)集合間合并:將一個(gè)整體拆成一個(gè)一個(gè)的個(gè)體,稱為扁平化
val list3 = List(8,9)
//val list4 = list3::list1
val list4 = list3:::list1
//(6)取指定數(shù)據(jù)
println(list(0))
//(3)遍歷 List
//list.foreach(println)
//list1.foreach(println)
//list3.foreach(println)
//list4.foreach(println)
list5.foreach(println)
}
}
list運(yùn)算符
package test
/**
* scala中的:: , +:, :+, :::, +++, 等操作;
*/
object listTest {
def main(args: Array[String]): Unit = {
val list = List(1,2,3)
// :: 用于的是向隊(duì)列的頭部追加數(shù)據(jù),產(chǎn)生新的列表, x::list,x就會(huì)添加到list的頭部
println(4 :: list) //輸出: List(4, 1, 2, 3)
// .:: 這個(gè)是list的一個(gè)方法;作用和上面的一樣,把元素添加到頭部位置; list.::(x);
println( list.:: (5)) //輸出: List(5, 1, 2, 3)
// :+ 用于在list尾部追加元素; list :+ x;
println(list :+ 6) //輸出: List(1, 2, 3, 6)
// +: 用于在list的頭部添加元素;
val list2 = "A"+:"B"+:Nil //Nil Nil是一個(gè)空的List,定義為L(zhǎng)ist[Nothing]
println(list2) //輸出: List(A, B)
// ::: 用于連接兩個(gè)List類型的集合 list ::: list2
println(list ::: list2) //輸出: List(1, 2, 3, A, B)
// ++ 用于連接兩個(gè)集合,list ++ list2
println(list ++ list2) //輸出: List(1, 2, 3, A, B)
}
}
可變 ListBuffer
import scala.collection.mutable.ListBuffer
object TestList {
def main(args: Array[String]): Unit = {
//(1)創(chuàng)建一個(gè)可變集合
val buffer = ListBuffer(1,2,3,4)
//(2)向集合中添加數(shù)據(jù)
buffer.+=(5)
buffer.append(6)
buffer.insert(1,2)
//(3)打印集合數(shù)據(jù)
buffer.foreach(println)
//(4)修改數(shù)據(jù)
buffer(1) = 6
buffer.update(1,7)
//(5)刪除數(shù)據(jù)
buffer.-(5)
buffer.-=(5)
buffer.remove(5)
}
}
Set 集合
不可變 Set
object TestSet {
def main(args: Array[String]): Unit = {
//(1)Set 默認(rèn)是不可變集合,數(shù)據(jù)無(wú)序
val set = Set(1,2,3,4,5,6)
//(2)數(shù)據(jù)不可重復(fù)
val set1 = Set(1,2,3,4,5,6,3)
//(3)遍歷集合
for(x<-set1){
println(x)
}
}
}
可變 mutable.Set
object TestSet {
def main(args: Array[String]): Unit = {
//(1)創(chuàng)建可變集合
val set = mutable.Set(1,2,3,4,5,6)
//(3)集合添加元素
set += 8
//(4)向集合中添加元素,返回一個(gè)新的 Set
val ints = set.+(9)
println(ints)
println("set2=" + set)
//(5)刪除數(shù)據(jù)
set-=(5)
//(2)打印集合
set.foreach(println)
println(set.mkString(","))
}
}
Map 集合
object TestMap {
def main(args: Array[String]): Unit = {
// Map
//(1)創(chuàng)建不可變集合 Map
val map = Map( "a"->1, "b"->2, "c"->3 )
//(3)訪問(wèn)數(shù)據(jù)
for (elem <- map.keys) {
// 使用 get 訪問(wèn) map 集合的數(shù)據(jù),會(huì)返回特殊類型 Option(選項(xiàng)):
有值(Some),無(wú)值(None)
println(elem + "=" + map.get(elem).get)
}
//(4)如果 key 不存在,返回 0
println(map.get("d").getOrElse(0))
println(map.getOrElse("d", 0))
//(2)循環(huán)打印
map.foreach((kv)=>{println(kv)})
}
}
可變 Map
object TestSet {
def main(args: Array[String]): Unit = {
//(1)創(chuàng)建可變集合
val map = mutable.Map( "a"->1, "b"->2, "c"->3 )
//(3)向集合增加數(shù)據(jù)
map.+=("d"->4)
// 將數(shù)值 4 添加到集合,并把集合中原值 1 返回
val maybeInt: Option[Int] = map.put("a", 4)
println(maybeInt.getOrElse(0))
//(4)刪除數(shù)據(jù)
map.-=("b", "c")
//(5)修改數(shù)據(jù)
map.update("d",5)
map("d") = 5
//(2)打印集合
map.foreach((kv)=>{println(kv)})
}
}
元組
object TestTuple {
def main(args: Array[String]): Unit = {
//(1)聲明元組的方式:(元素 1,元素 2,元素 3)
val tuple: (Int, String, Boolean) = (40,"bobo",true)
//(2)訪問(wèn)元組
//(2.1)通過(guò)元素的順序進(jìn)行訪問(wèn),調(diào)用方式:_順序號(hào)
println(tuple._1)
println(tuple._2)
println(tuple._3)
//(2.2)通過(guò)索引訪問(wèn)數(shù)據(jù)
println(tuple.productElement(0))
//(2.3)通過(guò)迭代器訪問(wèn)數(shù)據(jù)
for (elem <- tuple.productIterator) {
println(elem)
}
//(3)Map 中的鍵值對(duì)其實(shí)就是元組,只不過(guò)元組的元素個(gè)數(shù)為 2,稱之為
對(duì)偶
val map = Map("a"->1, "b"->2, "c"->3)
val map1 = Map(("a",1), ("b",2), ("c",3))
map.foreach(tuple=>{println(tuple._1 + "=" + tuple._2)})
}
}
操作
通用操作
object TestList {
def main(args: Array[String]): Unit = {
val list: List[Int] = List(1, 2, 3, 4, 5, 6, 7)
//(1)獲取集合長(zhǎng)度
println(list.length)
//(2)獲取集合大小,等同于 length
println(list.size)
//(3)循環(huán)遍歷
list.foreach(println)
//(4)迭代器
for (elem <- list.itera tor) {
println(elem)
}
while (iter.hasNext){
println(iter.next())
}
//(5)生成字符串
println(list.mkString(","))
//(6)是否包含
println(list.contains(3)) //如果存在返回true,不存在返回false
}
}
衍生集合操作
object TestList {
def main(args: Array[String]): Unit = {
val list1: List[Int] = List(1, 2, 3, 4, 5, 6, 7)
val list2: List[Int] = List(4, 5, 6, 7, 8, 9, 10)
//(1)獲取集合的頭
//獲取集合的頭使用head方法,可迭代的類型都可以用,一般在有序的類型里面有,無(wú)序的不考慮頭和尾
println(list1.head) //1
//(2)獲取集合的尾(不是頭的就是尾)
println(list1.tail) //List(2, 3, 4, 5, 6, 7)
//(3)集合最后一個(gè)數(shù)據(jù)
println(list1.last) //7
//(4)集合初始數(shù)據(jù)(不包含最后一個(gè))
println(list1.init) //List(1, 2, 3, 4, 5, 6)
//(5)反轉(zhuǎn)
println(list1.reverse)
//(6)取前(后)n 個(gè)元素
println(list1.take(3))
println(list1.takeRight(3))
//(7)去掉前(后)n 個(gè)元素
println(list1.drop(3))
println(list1.dropRight(3))
//兩個(gè)集合的操作
//(8)并集
println(list1.union(list2))
println(list1 ::: list2)
/如果是set做并集。那么重復(fù)的數(shù)據(jù)會(huì)被去重
val set = Set(6,12,33,45,56)
val set2 = Set(32,65,45,46,321,6)
val union2 = set.union(set2)
println(union2)
println(set ++ set2)
//(9)交集
println(list1.intersect(list2))
//(10)差集
println(list1.diff(list2))
//(11)拉鏈 注:如果兩個(gè)集合的元素個(gè)數(shù)不相等,那么會(huì)將同等數(shù)量的數(shù)據(jù)進(jìn)行拉鏈,多余的數(shù)據(jù)省略不用
println(list1.zip(list2))
// (12) 滑窗
//滑窗的意思是,第一次取123元素,第二次去234,每次取三個(gè)這樣滑下去,每次取多少可以定義
println(list.sliding(3)) //滑窗使用sliding方法,里面的參數(shù)是每次滑的元素是幾個(gè),可以看到是一個(gè)迭代器
for(i <- list.sliding(3)){ //使用類似于迭代器的方式遍歷出來(lái)
println(i)
}
println("================")
//要是里面有兩個(gè)參數(shù)的話,第二個(gè)參數(shù)是步長(zhǎng),一個(gè)參數(shù)的時(shí)候默認(rèn)步長(zhǎng)是1
for(i <- list.sliding(3,2)){
println(i)
}
}
}
計(jì)算函數(shù)
object TestList {
def main(args: Array[String]): Unit = {
val list: List[Int] = List(1, 5, -3, 4, 2, -7, 6)
//(1)求和
println(list.sum)
//(2)求乘積
println(list.product)
//(3)最大值
println(list.max)
//(4)最小值
println(list.min)
}
}
排序
sorted
println(list.sorted) //這是升序,從小到大
println(list.sorted.reverse) //降序可以先排序然后翻轉(zhuǎn)列表,可以達(dá)到效果
println(list.sorted(Ordered[Int])) //降序
sortBy
println(list.sortBy(x => x)) //按照元素大小排序
println(list.sortBy(x => x.abs)) //按照元素的絕對(duì)值大小排序
sortWith
println(list.sortWith((x, y) => x < y)) //按元素大小升序排序
println(list.sortWith((x, y) => x > y)) //按元素大小降序排序
計(jì)算高級(jí)函數(shù)
(1) 過(guò)濾
遍歷一個(gè)集合并從中獲取滿足指定條件的元素組成一個(gè)新的集合
(2) 轉(zhuǎn)換/映射(map)
將集合中的每一個(gè)元素映射到某一個(gè)函數(shù)
(3) 扁平化 (flatten)
有點(diǎn)像兩個(gè)列表要合并,列表里面還套著列表,我們要將他打散,這樣的操作就叫做扁平化
(4) 扁平化+映射 注:flatMap相當(dāng)于先進(jìn)行map操作,再進(jìn)行flatten操作集合中的每個(gè)元素的子元素映射到某個(gè)函數(shù)并返回新的集合
就是將多個(gè)集合展開(kāi),組合成新的一個(gè)集合。
(5) 分組(group)
按照指定的規(guī)則對(duì)集合的元素進(jìn)行分組,分組是轉(zhuǎn)換成了map
(6) 簡(jiǎn)化(reduce歸約)
通過(guò)指定的邏輯將集合中的數(shù)據(jù)進(jìn)行聚合,從而減少數(shù)據(jù),最
(7) 折疊(fold)
object TestList {
def main(args: Array[String]): Unit = {
val list: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
val nestedList: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9))
val wordList: List[String] = List("hello world", "hello atguigu", "hello scala")
//(1)過(guò)濾
println(list.filter(x => x % 2 == 0))
//(2)轉(zhuǎn)化/映射
println(list.map(x => x + 1))
//(3)扁平化
println(nestedList.flatten)
//(4)扁平化+映射 注:flatMap 相當(dāng)于先進(jìn)行 map 操作,在進(jìn)行 flatten操作
println(wordList.flatMap(x => x.split(" ")))
//(5)分組
println(list.groupBy(x => x % 2))
}
}
//reduce
object TestReduce {
def main(args: Array[String]): Unit = {
val list = List(1,2,3,4)
// 將數(shù)據(jù)兩兩結(jié)合,實(shí)現(xiàn)運(yùn)算規(guī)則
val i: Int = list.reduce( (x,y) => x-y )
println("i = " + i)
// 從源碼的角度,reduce 底層調(diào)用的其實(shí)就是 reduceLeft
//val i1 = list.reduceLeft((x,y) => x-y)
// ((4-3)-2-1) = -2
val i2 = list.reduceRight((x,y) => x-y)
println(i2)
}
}
//Fold
list(1,2,3,4)
//10+1+2+3+4
println(list.fold(10)(_+_))
//10-1-2-3-4
list.foldLeft(10)(_-_)
//1-(2-(3-(4-10)))
list.foldRight(10)(_-_)
實(shí)例
map1++map2 如果有相同的key,map1的value會(huì)被map2的value覆蓋
object TestFold {
def main(args: Array[String]): Unit = {
// 兩個(gè) Map 的數(shù)據(jù)合并
val map1 = mutable.Map("a"->1, "b"->2, "c"->3)
val map2 = mutable.Map("a"->4, "b"->5, "d"->6)
//fold 要求兩個(gè)()()里 的變量相同
val map3: mutable.Map[String, Int] = map2.foldLeft(map1)
{
(map, kv) => {
val k = kv._1
val v = kv._2
map(k) = map.getOrElse(k, 0) + v
map
}
}
println(map3)
}
}
WordCount 案例
package com.qihang.bigdata.spark.core
class Person(){}
object Test {
def main(args: Array[String]): Unit = {
//數(shù)據(jù)
val stringList:List[String]=List(
"hello",
"hello world",
"hello scala",
"hello spark from scala",
"hello flink from scala"
)
//對(duì)字符串切分,打散所有單詞的列表
// val wordList1 = stringList.map(_.split(" "))
// val wordList2 = wordList1.flatten
val wordList = stringList.flatMap(_.split(" "))
println(wordList) //List(hello, hello, world, hello, scala, hello, spark, from, scala, hello, flink, from, scala)
val groupMap = wordList.groupBy(word => word)
println(groupMap) //Map(world -> List(world), flink -> List(flink), spark -> List(spark), scala -> List(scala, scala, scala), from -> List(from, from), hello -> List(hello, hello, hello, hello, hello))
//對(duì)分組之后的list去長(zhǎng)度,當(dāng)成value
val countMap : Map[String,Int]= groupMap.map(kv => (kv._1, kv._2.length))
//排序,需要轉(zhuǎn)化為list,進(jìn)行排序,取前三
val sortList:List[(String,Int)]=countMap.toList
.sortWith( _._2 > _._2)
.take(3)
println(sortList)
}
}
復(fù)雜案例
package com.qihang.bigdata.spark.core
class Person(){}
object Test {
def main(args: Array[String]): Unit = {
//數(shù)據(jù)
val stringList:List[(String,Int)]=List(
("hello",1),
("hello world",2),
("hello scala",3),
("hello spark from scala",1),
("hello flink from scala",2)
)
//思路1:打散,變成上一個(gè)案例
val newStringList:List[String]=stringList.map(
kv=>{
(kv._1.trim + " ")*kv._2
}
)
val wordCountList:List[(String,Int)]=newStringList
.flatMap(_.split(" "))
.groupBy(word=>word)
.map(kv=>(kv._1,kv._2.length))
.toList
.sortBy(_._2)(Ordering[Int].reverse) //降序排序
.take(3)
//2 基于預(yù)處理直接進(jìn)行處理
//將字符串打散,并和個(gè)數(shù)包裝成二元組
val preCountList:List[(String,Int)] = stringList.flatMap(
tuple =>{
val strings:Array[String]=tuple._1.split(" ")
strings.map( word => (word, tuple._2) )
}
)
println(preCountList)
//List((hello,1), (hello,2), (world,2), (hello,3), (scala,3), (hello,1), (spark,1), (from,1), (scala,1), (hello,2), (flink,2), (from,2), (scala,2))
//對(duì)二元組進(jìn)行分組
val perCountMap:Map[String,List[(String,Int)]] = preCountList.groupBy( _._1 )
println(perCountMap)
//Map(world -> List((world,2)), flink -> List((flink,2)), spark -> List((spark,1)), scala -> List((scala,3), (scala,1), (scala,2)), from -> List((from,1), (from,2)), hello -> List((hello,1), (hello,2), (hello,3), (hello,1), (hello,2)))
//疊加每個(gè)單詞預(yù)統(tǒng)計(jì)的個(gè)數(shù)值
//mapValues 將原有的元素集轉(zhuǎn)換成新的元素集
val countMap = perCountMap.mapValues(
tupleList => tupleList.map(_._2).sum
)
println(countMap)
//Map(world -> 2, flink -> 2, spark -> 1, scala -> 6, from -> 3, hello -> 9)
//轉(zhuǎn)List 排序取前三
val countList = countMap.toList //List((world,2), (flink,2), (spark,1), (scala,6), (from,3), (hello,9))
.sortWith( _._2 > _._2 )
.take(3)
println(countList)
}
}
隊(duì)列
object TestQueue {
def main(args: Array[String]): Unit = {
val que = new mutable.Queue[String]()
que.enqueue("a", "b", "c")
println(que.dequeue())
println(que.dequeue())
println(que.dequeue())
}
}
并行集合
val result1 = (0 to 100).map{case _ =>
Thread.currentThread.getName}
val result2 = (0 to 100).par.map{case _ =>
Thread.currentThread.getName}
來(lái)源:
尚硅谷
(8條消息) scala中的:: , +:, :+, :::, +++, 等操作的含義_scala:::_JasonLee實(shí)時(shí)計(jì)算的博客-CSDN博客
?(11條消息) Scala 集合常用函數(shù)_scala滑窗_氣質(zhì)&末雨的博客-CSDN博客文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-408679.html
每天學(xué)一點(diǎn)Scala之 高階函數(shù) flatten_51CTO博客_scala高階函數(shù)文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-408679.html
到了這里,關(guān)于【Scala】集合的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!