Scala-集合

来源:https://www.cnblogs.com/POCOPOCOPOCO/archive/2022/10/20/16810760.html
-Advertisement-
Play Games

集合 Scala的集合有三大類: 序列Seq、集Set、映射Map 所有的集合都擴展自Iterable特質。對於幾乎所有的集合類 Scala都同時提供了可變和不可變的版本 可變集合 可以在適當的地方被更新或擴展。這意味著你可以修改,添加,移除一個集合的元素。 不可變集合 永遠不會改變。不過,你仍然可 ...


集合

Scala的集合有三大類:

序列Seq、集Set、映射Map

所有的集合都擴展自Iterable特質。對於幾乎所有的集合類

Scala都同時提供了可變和不可變的版本

可變集合

可以在適當的地方被更新或擴展。這意味著你可以修改,添加,移除一個集合的元素。

不可變集合

永遠不會改變。不過,你仍然可以模擬添加,移除或更新操作。

但是這些操作將在每一種情況下都返回一個新的集合,同時使原來的集合不發生改變,

所以這裡的不可變並不是變數本身的值不可變,而是變數指向的那個記憶體地址不可變

集合特質

-- scala.collection.immutable

image

-- scala.collection.mutable

image

數組(array)

嚴格意義上,數組不是集合

scala中給數組一個特定的類型:Array

構建Scala中的數組,其實等同於構造Java的數組

不可變數組

基本語法

  • 數組定義

    // 集合分為兩大類:可變集合,不可變集合
    // Scala預設提供的集合都是不可變。
    //        val array = new Array[String](3)
    //        array(0) = "a"
    //        array(1) = "a"
    //        array(2) = "a"
    // 使用集合的伴生對象構建集合,並同時初始化
    val array1 = Array(1,2,3,4)
    val array2 = Array(5,6,7,8)
    //val array2 = Array.apply(1,2,3,4)
    
  • 數組賦值

    • 修改某個元素的值

      arr01(3) = 10
      val i = 10
      arr01(i/3) = 20
      
    • 採用方法的形式修改數組的值

      arr01.update(0,1)
      
  • 遍曆數組

    • 查看數組

      println(arr01.mkString(","))
      
    • 普通遍歷

      for (i <- arr01) {
      	println(i)
      }
      
    • 簡化遍歷

      def printx(elem:Int): Unit = {
      	println(elem)
      }
      arr01.foreach(printx)
      arr01.foreach((x)=>{println(x)})
      arr01.foreach(println(_))
      arr01.foreach(println)
      

基本操作

  • 添加數組元素,創建新數組
val arr1 = Array(1,2,3,4)
val arr3: Array[Int] = arr1 :+ 5
println( arr1 eq arr3 ) // false
arr3.foreach(println)
// 12345
  • 添加集合
val arr1 = Array(1,2,3,4)
val arr2 = Array(5,6,7,8)
val arr5: Array[Int] = arr1 ++ arr2    
arr5.foreach(println)
// 12345678
  • 多維數組
var myMatrix = Array.ofDim[Int](3,3)
myMatrix.foreach(list=>println(list.mkString(",")))
//    0,0,0
//    0,0,0
//    0,0,0
  • 合併數組
val arr1 = Array(1,2,3,4)
val arr2 = Array(5,6,7,8)
// 合併數組
val arr6: Array[Int] = Array.concat(arr1, arr2)
arr6.foreach(println)
// 12345678
  • 創建指定範圍的數組
// 創建指定範圍的數組
val arr7: Array[Int] = Array.range(0,2)
arr7.foreach(println)
// 01
  • 創建並填充指定數量的數組
val arr8:Array[Int] = Array.fill[Int](5)(-1)
arr8.foreach(println)

可變數組

基本語法

  • 創建可變數組
val buffer = new ArrayBuffer[String]()
val buffer = ArrayBuffer("a", "b", "c")
println(buffer)
// ArrayBuffer(a, b, c)
  • 增加數據
buffer.append("a", "b", "c", "d")
// ArrayBuffer(a, b, c, a, b, c, d)
buffer.appendAll(Array("a", "b", "c"))
// ArrayBuffer(a, b, c, a, b, c, d, a, b, c)


val buffer1 = ArrayBuffer(1,2,3,4)
val buffer2 = ArrayBuffer(5,6,7,8)
val buffer3: ArrayBuffer[Int] = buffer1 += 5
println( buffer1 eq buffer3 ) // true

// 使用 ++ 運算符會產生新的集合數組
val buffer4: ArrayBuffer[Int] = buffer1 ++ buffer2
// 使用 ++= 運算符會更新之前的集合,不會產生新的數組
val buffer5: ArrayBuffer[Int] = buffer1 ++= buffer2
println( buffer1 eq buffer4 ) // false
println( buffer1 eq buffer5 ) // true
  • 修改數據
buffer.update(0, "e")
buffer(0) = "e"
  • 刪除數據
val buffer = ArrayBuffer("a", "b", "c")
buffer.remove(2) // ArrayBuffer(a, b)
val buffer = ArrayBuffer("a","b","c","a","b","c","d")
buffer.remove(2,2) // ArrayBuffer(a, b, b, c, d)


val strings: ArrayBuffer[String] = buffer - "a"
println(buffer eq strings)
println(buffer)
println(strings)

// false
// ArrayBuffer(a, b, c)
// ArrayBuffer(b, c)
  • 查詢數據
println(buffer(3))
  • 迴圈集合
for ( i <- buffer ) {
println(i)
}

可變數組和不可變數組轉換

val buffer = ArrayBuffer(1,2,3,4)
val array = Array(4,5,6,7)

// 將不可變數組轉換為可變數組
val buffer1: mutable.Buffer[Int] = array.toBuffer
// 將可變數組轉換為不可變數組
val array1: Array[Int] = buffer.toArray

數組方法

val array = Array(1,2,3,4)

println(array.size) // 4
println(array.length) // 4
println(array.isEmpty) // false
println(array.contains(2)) // true  判斷集合中是否包含某個元素
println(array.distinct.mkString(",")) // 1,2,3,4
println(array.reverse.mkString(",")) // 4,3,2,1

println(array.mkString(",")) // 1,2,3,4
array.foreach(println)
// 1
// 2
// 3
// 4
val iterator = array.iterator  // 生成迭代器
while (iterator.hasNext){
println(iterator.next())
}
// 1
// 2
// 3
// 4


val array = ArrayBuffer(1,2,3,4)

// 從集合中獲取部分數據
println(array.head) // 1
println(array.tail) // ArrayBuffer(2, 3, 4)
println(array.tails) // <iterator>
println(array.last) // 4
println(array.init) // 初始 ArrayBuffer(1, 2, 3) 返回當前序列中不包含最後一個元素的序列(去尾)
println(array.inits) // <iterator> 對集合中的元素進行 init 操作,該操作的返回值中, 第一個值是當前序列的副本,包含當前序列所有的元素,最後一個值是空的,對頭尾之間的值進行init操作,上一步的結果作為下一步的操作對象

// 取前幾個
println(array.take(3)) // ArrayBuffer(1, 2, 3)
println(array.reverse.take(2).reverse) // ArrayBuffer(3, 4)
println(array.takeRight(2)) // ArrayBuffer(3, 4)
println(array.drop(1)) // ArrayBuffer(2, 3, 4)
println(array.dropRight(1)) // ArrayBuffer(1, 2, 3)


val array = ArrayBuffer(1,2,3,4,5)

println(array.sum) // 15 加法
println(array.max) // 5
println(array.min) // 1
println(array.product) // 120 乘法

LEFT與RIGHT計算

// 自定義數據操作的方法
// 集合的數據無論是多少,最基本的數據操作其實都是兩兩計算。
// map => reduce => 簡化,規約(聚合)

def reduceFunction(x : Int, y : Int): Int = {
    x + y
}

//println(array.reduce(reduceFunction))
//println(array.reduce((x:Int, y:Int)=>{x + y}))
//println(array.reduce((x:Int, y:Int)=>x + y))
//println(array.reduce((x, y)=>x + y))
println(array.reduce(_ - _))  // -13

// reversed.reduceLeft[B]((x, y) => op(y, x))
// 【1,2,3,4, 5】
// 【5,4,3,2,1】
//  1 - (2 - (3 - (4 - 5)))
println(array.reduceRight(_ - _)) // 3
1 - ( 2 - ( 3 - ( 4 - 5 ) ) )
println(array.reduceLeft(_ - _)) // -13
( ( ( 1 - 2 ) - 3 ) - 4 ) - 5 

fold與scan

val array = ArrayBuffer(1,2,3,4)
val num = 5

// 摺疊
println(array.fold(5)(_ - _)) // -5

// (((5 - 1) - 2) - 3) - 4
println(array.foldLeft(5)(_ - _)) // -5

// reversed.foldLeft(z)((x, y) => op(y, x))
// 【1,2,3,4】
// 【4,3,2,1】
//  1 - (2  - (3 - (4 - 5)))
println(array.foldRight(5)(_ - _)) // 3

println(array.scan(5)(_ - _)) // ArrayBuffer(5, 4, 2, -1, -5)
println(array.scanLeft(5)(_-_)) // ArrayBuffer(5, 4, 2, -1, -5)
println(array.scanRight(5)(_-_)) // ArrayBuffer(3, -2, 4, -1, 5)

map

val array = ArrayBuffer(1,2,3,4)

// TODO 功能函數:由集合對象提供函數執行自定義的功能
//  1. map => 映射(轉換) => K->V
//     a => b

// map方法需要傳遞一個參數,這個參數的類型為函數類型: Int => B
def mapFunction( num:Int ): Int = {
    num * 2
}

println(array.map(mapFunction)) // ArrayBuffer(2, 4, 6, 8)

println(array.map(
    (num:Int) => {
        num * 2
		}
	)) // ArrayBuffer(2, 4, 6, 8)

println(array.map(_*2)) // ArrayBuffer(2, 4, 6, 8)

扁平化操作(flatten)

  • 將整體拆分成個體的操作,稱之為扁平化
  • 扁平化操作只能對最外層進行操作
    val array = ArrayBuffer(
      ArrayBuffer(
        ArrayBuffer(1,2),ArrayBuffer(5,6)
      ), ArrayBuffer(
        ArrayBuffer(3,4),ArrayBuffer(7,8)
      )
    )
    println(array.flatten.flatten)
    // ArrayBuffer(1, 2, 5, 6, 3, 4, 7, 8)

split

        val array = Array(
            "Hello Scala", "Hello Hadoop"
        )

        println(array.flatten.mkString(","))
	    // H,e,l,l,o, ,S,c,a,l,a,H,e,l,l,o, ,H,a,d,o,o,p

        println(array.flatMap(
            str => {
                str.split(" ")
            }
        ).mkString(","))
        // Hello,Scala,Hello,Hadoop

filter

filter方法可以對集合中的每一條數據進行篩選過濾
滿足條件(true)的數據保留,不滿足條件(false)的數據丟棄

        val array = ArrayBuffer(1,2,3,4)
        val r = array.filter(
            num => {
                num % 2 != 0
            }
        )
        println(r) // ArrayBuffer(1, 3)

GroupBy

根據指定的規則對每一條數據進行分組

        val array = ArrayBuffer(1,2,3,4)
        // 根據指定的規則對每一條數據進行分組
        val r = array.groupBy(
            num => {
                if ( num % 2 == 0 ) {
                    "偶數"
                } else {
                    "奇數"
                }
                num % 2
            }
        )
        println(r) // Map(1 -> ArrayBuffer(1, 3), 0 -> ArrayBuffer(2, 4))
        val array2 = ArrayBuffer(
            "Hello", "Scala", "Hadoop", "Spark"
        )

        println(array2.groupBy(_.substring(0, 1)))
        // Map(S -> ArrayBuffer(Scala, Spark), H -> ArrayBuffer(Hello, Hadoop))

sortBy

排序:通過指定的規則對每一條數據進行排序處理, 預設為升序

        val array = ArrayBuffer("1", "11", "2", "3", "22")
        println(array.sortBy(
            num => num.toInt
        )) // ArrayBuffer(1, 2, 3, 11, 22)
        println(array.sortBy(num => num.toInt)(Ordering.Int.reverse)) // ArrayBuffer(22, 11, 3, 2, 1)

WordCount

        // TODO 1. 讀取文件,獲取原始數據
        //  line => Hello Scala
        val source: BufferedSource = Source.fromFile("data/word.txt")
        val lines: Array[String] = source.getLines().toArray
        source.close()

        // TODO 2. 將原始數據進行切分成一個一個的單詞
        // "Hello Scala" => "Hello", "Scala"
        val words = lines.flatMap(
            line => {
                line.split(" ")
            }
        )

        // TODO 3. 對分詞的結果進行分組操作(相同的單詞放置在一起)
        // "Hello", "Hello" => { "Hello"=>List( Hello, Hello ) }
        val wordGroup: Map[String, Array[String]] = words.groupBy(word => word)

        // TODO 4. 對分組後的數據進行數量的統計
        // 如果數據在轉換時,無需對key進行操作,只對v進行處理時,可以使用mapValues方法
        // { "Hello"=>List( Hello, Hello ) }
        // =>
        // { "Hello"=>2 }
        val wordCount = wordGroup.mapValues(
            v => {
                v.size
            }
        )
        
// fun2
//        val wordCount = wordGroup.map {
//            case (word, list) => {
//                (word, list.size)
//            }
//        }

        // TODO 5. 將統計結果列印在控制台
        println(wordCount)

簡化代碼

        val source: BufferedSource = Source.fromFile("data/word.txt")
        val lines: Array[String] = source.getLines().toArray
        source.close()

        val wordCount =
            lines
                .flatMap(_.split(" "))
                .groupBy(word => word)
                .mapValues(_.size)

        println(wordCount)

合併count01

        val list = List(
            ("Hello Scala", 4),
            ("Hello World", 2)
        )
        val list2 = list.map(
            t => {
                val line = t._1
                val cnt = t._2
                (line + " ") * cnt // 連詞
            }
        )
        println(list2)
// List(Hello Scala Hello Scala Hello Scala Hello Scala , Hello World Hello World )

合併count02

        val list = List(
            ("Hello Scala", 4),
            ("Hello World", 2)
        )

        // ("Hello Scala", 4) => ("Hello", 4),("Scala", 4)
        // ("Hello World", 2) => ("Hello", 2),("World", 2)
        val list1 = list.flatMap(
            t => {
                val line = t._1
                val cnt = t._2

                val datas = line.split(" ") // Hello,Scala => (Hello, 4), (Scala, 4)
                datas.map(
                    word => {
                        (word, cnt)
                    }
                )

            }
        )
        val groupData: Map[String, List[(String, Int)]] = list1.groupBy(_._1)

        /*
           Map(
               Hello -> List((Hello,4), (Hello,2)),
               Scala -> List((Scala,4)),
               World -> List((World,2)))

           Map(
               Hello -> List(4, 2),
               Scala -> List(4),
               World -> List(2))

           Map(
               Hello -> 6,
               Scala -> 4,
               World -> 2
         */
        val groupData1 = groupData.mapValues(
            list => {
                list.map(_._2).sum
            }
        )

        println(groupData1)

Seq集合(List)

基本語法

  • 聲明

    // 一般會從採用List
    val seq = Seq(1,2,3,4)
    val list = List(1,2,3,4)
    val list1 = List(5,6,7,8)
    
  • 數據操作

    val ints: List[Int] = list :+ 5
    println(list eq ints) // false
    val ints1: List[Int] = 5 +: list
    println(list) // List(1, 2, 3, 4)
    println(ints) // List(1, 2, 3, 4, 5)
    println(ints1) // List(5, 1, 2, 3, 4)
    
  • Nil 在集合中表示空集合

    val ints2 = 1 :: 2:: 3 :: Nil
    //Nil.::(3).::(2).::(1)
    val ints3 = 1 :: 2 :: 3 :: list1 ::: Nil
    println(Nil) // List()
    println(ints2) // List(1, 2, 3)
    println(ints3) // List(1, 2, 3, 5, 6, 7, 8)
    
  • 數據有序,可以放重覆數據

    val list = List(1,3,4,2,1)
    println(list) // List(1, 3, 4, 2, 1)
    

方法

  • 插入

    val list = ListBuffer(1,3,4,2,1)
    val list2 = ListBuffer(1,3,4,2,1)
    
    list.append(1)
    println(list)
    list.appendAll(list2)
    println(list)
    list.insert(0,10)
    println(list)
    
    // ListBuffer(1, 3, 4, 2, 1, 1)
    // ListBuffer(1, 3, 4, 2, 1, 1, 1, 3, 4, 2, 1)
    // ListBuffer(10, 1, 3, 4, 2, 1, 1, 1, 3, 4, 2, 1)
    
  • 更新

    val list = ListBuffer(1,3,4,2,1)
    list.update(0, 5) // 改變自身
    println(list)
    list.updated(0, 6) // 創建新的
    println(list)
    println(list.updated(0, 6))
    //    ListBuffer(5, 3, 4, 2, 1)
    //    ListBuffer(5, 3, 4, 2, 1)
    //    ListBuffer(6, 3, 4, 2, 1)
    
  • 刪除

    val list = ListBuffer(1,3,4,2,1)
    list.remove(1)
    println(list)
    list.remove(1,2)
    println(list)
    // ListBuffer(1, 4, 2, 1)
    // ListBuffer(1, 1)
    
  • 遍歷

    val list = ListBuffer(1,3,4,2,1)
    println(list.mkString(","))
    val iterator = list.iterator
    while (iterator.hasNext) {
    	println(iterator.next())
    }
    list.foreach(println)
    //  1,3,4,2,1
    //  1
    //  3
    //  4
    //  2
    //  1
    //  1
    //  3
    //  4
    //  2
    //  1
    
  • 類型轉換

    val list = ListBuffer(1,3,4,2,1)
    val list1 = list.toList
    val list2 = list1.toBuffer
    

Set集合

數據無序,不可重覆

// update方法用於更新set集合
set.update(5, true)
println(set)
set.update(4, false)
println(set)
set.remove(3)

// Set(1, 5, 2, 3, 4)
// Set(1, 5, 2, 3)
// Set(1, 5, 2)

set.foreach(println) //遍曆數據

交集與差集

    val set1 = mutable.Set(1,2,3,4)
    val set2 = mutable.Set(4,5,6,7)

    // 交集
    val set3: mutable.Set[Int] = set1 & set2
    println(set3.mkString(",")) // 4
    // 差集
    val set4: mutable.Set[Int] = set1 &~ set2
    println(set4.mkString(",")) // 1,2,3

Map集合

Map(映射)是一種可迭代的鍵值對(key/value)結構。所有的值都可以通過鍵來獲取。Map 中的鍵都是唯一的。

數據無序,K不能重覆的集合

  • 不可變Map

    val map = Map(
                "a" -> 1, "b" -> 2, "a" -> 3,"d" -> 4,"e" -> 5
            )
    val map1 = mutable.Map(
            "a" -> 1, "b" -> 2, "a" -> 3,"d" -> 4,"e" -> 5
            ) // K不能重覆的集合
    map1.put("f", 6)
    println(map1) // Map(e -> 5, b -> 2, d -> 4, a -> 3, f -> 6)
    map1.update("a", 7)
    println(map1) // Map(e -> 5, b -> 2, d -> 4, a -> 7, f -> 6)
    map1.remove("e")
    println(map1) // Map(b -> 2, d -> 4, a -> 7, f -> 6)
    
            // java中從HashMap中獲取一個不存在的key,會返回null
            //       HashMap允許放空鍵(Key)空值(Value)
            val map1 = mutable.Map(
                "a" -> 1, "b" -> 2, "a" -> 3,"d" -> 4,"e" -> 5
            )
            
            val maybeInt1: Option[Int] = map1.get("f")
    
            // Option類型專門為瞭解決空指針問題設計的
            // Option : 選項,對象只有2個 Some, None
            if ( maybeInt1.isEmpty ) {
                println("沒有對應key的值, 提供預設值 : " + maybeInt1.getOrElse(0))
            } else {
                println("對應key的值為" + maybeInt1.get)
            }// print --> 沒有對應key的值, 提供預設值 : 0
    		
            println("獲取指定key的值:" + maybeInt1.getOrElse(0)) // print--> 獲取指定key的值:0
            // 如果不存在,獲取預設值
    
            println(map1.getOrElse("a", 0)) // 3
            //獲取可能存在的key值, 如果不存在就使用預設值
    

Tuple元組

可以將無關的元素組合在一起,形成一個整體來進行訪問,這種整體結構稱之元素組合

因為元組中的數據沒有關係,所以只能通過順序號進行訪問

val t : (Int, String, Int) = (1, "zhangsan", 30)
println(t._1) // 1
println(t._2) // zhangsan
println(t._3) // 30
// Tuple也是一個集合對象,所以也有類型
// (Int, String, Int)
// scala中元組也有專門的類型
val t1 : Tuple3[Int, String, Int] = (1, "zhangsan", 30)
// Tuple類型最多存放元素的數量為22個。但是類型沒有約束的。
println(t) // (1,zhangsan,30)

如果元組中的元素只有2個,稱之為對偶元組,也可以稱之為鍵值對

        val kv = (1, "zhangsan")
        val map = Map(
            ("a", 1), ("b", 2), ("c", 3)
        )
        map.foreach(
            t => {
                println(t._1 + "=" + t._2)
            }
        )
        println(map)
        // a=1
        // b=2
        // c=3
        // Map(a -> 1, b -> 2, c -> 3)

將Map轉換為List

val list: List[(String, Int)] = map.toList

不同省份的商品點擊排行

        // 不同省份的商品點擊排行
        // word(省份-商品) - count(1)
        val datas = List(
            ("zhangsan", "河北", "鞋"),
            ("lisi", "河北", "衣服"),
            ("wangwu", "河北", "鞋"),
            ("zhangsan", "河南", "鞋"),
            ("lisi", "河南", "衣服"),
            ("wangwu", "河南", "鞋"),
            ("zhangsan", "河南", "鞋"),
            ("lisi", "河北", "衣服"),
            ("wangwu", "河北", "鞋"),
            ("zhangsan", "河北", "鞋"),
            ("lisi", "河北", "衣服"),
            ("wangwu", "河北", "帽子"),
            ("zhangsan", "河南", "鞋"),
            ("lisi", "河南", "衣服"),
            ("wangwu", "河南", "帽子"),
            ("zhangsan", "河南", "鞋"),
            ("lisi", "河北", "衣服"),
            ("wangwu", "河北", "帽子"),
            ("lisi", "河北", "衣服"),
            ("wangwu", "河北", "電腦"),
            ("zhangsan", "河南", "鞋"),
            ("lisi", "河南", "衣服"),
            ("wangwu", "河南", "電腦"),
            ("zhangsan", "河南", "電腦"),
            ("lisi", "河北", "衣服"),
            ("wangwu", "河北", "帽子")
        )
        // TODO 將原始數據進行結構的轉換
        // (人,省份,商品) => (省份-商品, 1)
        val mapDatas = datas.map(
            t => {
                (t._2 + "-" + t._3, 1)
            }
        )
        // TODO 將轉換結構後的數據進行分組
        val groupDatas: Map[String, List[(String, Int)]] = mapDatas.groupBy(_._1)

        // TODO 將分組後的數據進行統計聚合
        val cntDatas = groupDatas.mapValues(
            list => list.size
        )
        //println(cntDatas)
        // TODO 將聚合的結果進行結構的轉換
        // 將相同省份的數據準備放在一起
        // (省份-商品, count) => (省份,(商品,count))
        val mapDatas1 = cntDatas.toList.map(
            kv => {
                val k = kv._1
                val cnt = kv._2
                val ks = k.split("-")
                (ks(0), (ks(1), cnt))
            }
        )
		//        println(mapDatas1)
        // 河北 => List( (衣服,20),(鞋,10), )
        // TODO 將轉換結構後的數據進行排序(降序)
        val groupDatas1 =
            mapDatas1.groupBy(_._1).mapValues(
                list=> {
                    list.map(_._2).sortBy(_._2)(Ordering.Int.reverse).take(3)
                }
            )
        println(groupDatas1) 
        // Map(河南 -> List((鞋,6), (衣服,3), (電腦,2)), 河北 -> List((衣服,6), (鞋,4), (帽子,3)))

Queue隊列

Scala也提供了隊列(Queue)的數據結構,隊列的特點就是先進先出。進隊和出隊的方法分別為enqueue和dequeue。

val que = new mutable.Queue[String]()
// 添加元素
que.enqueue("a", "b", "c")
val que1: mutable.Queue[String] = que += "d"
println(que eq que1) // true
// 獲取元素
println(que.dequeue()) // a
println(que.dequeue()) // b 
println(que.dequeue()) // c

並行

Scala為了充分使用多核CPU,提供了並行集合(有別於前面的串列集合),用於多核環境的並行計算。

//        val result1 = (0 to 100).map{
//            x => {
//                Thread.currentThread.getName
//            }
//        } //      main, main, main, main, main, main, main,
        val result2 = (0 to 100).par.map{
             x =>  {
                 Thread.currentThread.getName // 查看線程名字
             }
        } //         scala-execution-context-global-23, scala-execution-context-global-13
        println(result1)
        println(result2)

常用方法

  • 快排

    val list = List(1,6,5,3,2,4)
    
    val tuple: (List[Int], List[Int]) = list.partition(
        num => {
            num > 3
        }
    )
    println(tuple._1)
    println(tuple._2)
    
  • 交集,並集,差集

    val list1 = List(1,2,3,4)
    val list2 = List(3,4,5,6)
    
    // 交集,並集,差集
    println(list1.intersect(list2))
    println(list1.union(list2))
    println(list1.diff(list2))
    
  • 滑動視窗

            val list1 = List(1,2,3,4,5,6,7,8)
    
            //println(list1.drop(1))
    
            //list1.head + list1.tail.head
    
            // 滑動視窗
            // 滾動視窗 當視窗大小等於步長是
            val iterator: Iterator[List[Int]] = list1.sliding(3, 3) //視窗大小,步長 
            while (iterator.hasNext) {
                val ints: List[Int] = iterator.next()
                println(ints)
            }
    
  • 拉鏈

            val list1 = List(1,2,3,4)
            val list2 = List(5,6,7,8,9, 10)
    
            // 所謂的拉鏈,其實就是將兩個集合相同的位置的數據連接在一起
            val tuples: List[(Int, Int)] = list1.zip(list2)
            println(tuples) // List((1,5), (2,6), (3,7), (4,8))
    
            println(list2.zipWithIndex)  // 自己和自己的索引拉鏈
            // List((5,0), (6,1), (7,2), (8,3), (9,4), (10,5))
    
  • 兩個map摺疊

            val map1 = mutable.Map(
                ("a", 1), ("b", 2), ("c", 3)
            )
            val map2 = mutable.Map(
                ("a", 4), ("d", 5), ("c", 6)
            )
    
            val map3 = map2.foldLeft(map1)(
                (map, kv) => {
                    val key = kv._1
                    val cnt = kv._2
                    val oldCnt = map.getOrElse(key, 0)
                    map.update(key, oldCnt + cnt)
                    map
                }
            )
            println(map3) // Map(b -> 2, d -> 5, a -> 5, c -> 9)
    
  • 使用匿名函數時,給定的參數直接放回,不能使用下劃線代替,必須完整,

    //        val newlist = list3.flatMap(
    //            list => { // 整體
    //                list  // 容器
    //            }
    //        )
    
            val words = list2.flatMap(
                str => {
                    str.split(" ") // 容器( Hello, Scala )
                }
            )
            
            
            // 簡化規則
            def test( f : (String)=>Unit ): Unit = {
                f("zhangsan")
            }
    
            test( (s:String)=>{println(s)} )
            test( (s:String)=>println(s) )
            test( (s)=>println(s) )
            test( s=>println(s) )
            test( s => println(s) )
    
  • 分組

            val list1 = List(1,2,3,4)
            val list2 = List("Hello", "Hive", "Hadoop")
            val list4 = List(
                ("a", 1), ("a", 2), ("a", 3)
            )
    
            // Map[ 組名1=>分組集合1,組名2=>分組集合2 ]
            val list3 = list4.groupBy(
                t => t._1
            )
    
            println(list3) // Map(a -> List((a,1), (a,2), (a,3)))
            
            val list5 = List(1,4,3,2,5)
    
            // 1 4 3 2 5
            // 1 0 1 0 1
            // 4 2 1 3 5
            // List(4, 2, 1, 3, 5)
            //println(list5.sortBy(_ % 2))  // 取餘後排序
    
  • 排序

            val user1 = new User()
            user1.age = 20
            user1.salary = 2000
            val user2 = new User()
            user2.age = 30
            user2.salary = 2000
            val user3 = new User()
            user3.age = 30
            user3.salary = 1000
    
            val users = List(
                user1, user2, user3
            )
    
            //println(users.sortBy(_.age)(Ordering.Int.reverse))
    
            // Tuple : 元組,可以預設排序,先比較第一個,如果相同,比較第二個,依此類推
    //        println(
    //            users.sortBy(
    //                user => {
    //                    ( user.age, user.salary )
    //                }
    //            )(Ordering.Tuple2[Int, Int]( Ordering.Int, Ordering.Int.reverse ))
    //        )
    
            // 自定義排序
            println(users.sortWith(
                (user1, user2) => {
                    // 將你期望的結果,返回為true
                    //user1.salary > user2.salary
                    if ( user1.age < user2.age ) {
                        true
                    } else if (user1.age == user2.age ) {
                        user1.salary < user2.salary
                    } else {
                        false
                    }
                }
            ))
    
    
        }
        class User {
            var age : Int = _
            var salary : Int = _
    
            override def toString: String = {
                return s"User[${age}, ${salary}]"
            }
        }
    

    S


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在開發中會遇到這樣的需求:獲取子組件的引用,並調用子組件中定義的方法。如封裝了一個表單組件,在父組件中需要調用這個表單組件的引用,並調用這個表單組件的校驗表單函數或重置表單函數。要實現這個功能,首先要在子組件中暴露父組件需要調用的函數,然後去父組件中獲取子組件的引用,最後通過子組件的引用調用子組件暴 ...
  • 在上一篇中,我們一起分析了 VS Code 整體的代碼架構,瞭解了 VS Code 是由前後端分離的方式開發的。且無論前端是基於 electron 還是 web,後端是本地還是雲端,其調用方式並無不同。 這樣的架構下,前後端的通信方式是如何實現的呢?本篇我們將一起來探究 VS Code For We ...
  • 每年的蘋果新產品發佈,其官網都會配套更新相應的單頁滾動產品介紹頁。其中的動畫特效都非常有意思,今年 iPhone 14 Pro 的介紹頁不例外。 最近,剛好有朋友問到,其對官網的一段文字特效特別感興趣,看適用簡單卻不知從何下手,我們來看看: 整個動畫大致是,隨著頁面的向下滾動,整個文字從無到出現,再 ...
  • call,apply,bind作為改變this指向的法寶,那麼它們是怎麼做到的呢,接下來嘗試邊分析、邊構造: 我們先來構造一個mycall骨架,把功能添加到原型鏈 讓函數依附於某個對象,並且以對象方法的方式執行,以此來改變this指向,需要註意: 為了避免不必要的覆蓋,我們使用Symbol作為key ...
  • 近期,數據中心系統負荷大,mysql伺服器的CPU動輒達到90%以上。代碼和數據表存在很大優化空間。 這裡分享一個定時任務批量處理數據的優化過程。 先介紹定時任務 先介紹下麵2張數據表 欄位 數據量 platform_order 平臺交易訂單表 有超過50多個欄位。 包括 主鍵自增id、客戶id、客 ...
  • 前言 嗨嘍~大家好呀,這裡是魔王吶 ! 國企文員和游戲陪玩兩個職業間,你會選擇哪個? 00後李明的答案是後者。 今年3月,某二本院校應屆畢業生李明,兜兜轉轉,沒有找到特別合心的工作 卻憑著還不錯的游戲技術,成為了全職的游戲陪玩。 “按單收費,大概一單大概兩三百元,按時長收費,一小時50到100元”, ...
  • 滿漢樓02 4.功能實現04 4.6顯示所有菜品 4.6.1思路分析 創建一個菜單表menu,在Domain層創建與菜單表對應的Javabean-Menu類,在DAO層創建MenuDAO,完成對menu表的增刪改查,在Service層創建一個和menu表相關的service類,service類提供給 ...
  • 在筆者之前的文章`《驅動開發:內核特征碼搜索函數封裝》`中我們封裝實現了特征碼定位功能,本章將繼續使用該功能,本次我們需要枚舉內核`LoadImage`映像回調,在Win64環境下我們可以設置一個`LoadImage`映像載入通告回調,當有新驅動或者DLL被載入時,回調函數就會被調用從而執行我們自己... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...