大数据技术之_16_Scala学习_08_数据结构(下)-集合操作+模式匹配

第十一章 数据结构(下)-集合操作11.1 集合元素的映射-map11.1.1 map 映射函数的操作11.1.2 高阶函数基本使用案例1+案例211.1.3 使用 map 映射函数来解决11.1.4 模拟实现 map 映射函数的机制11.1.5 课堂练习11.2 集合元素的扁平-flatMap11.3 集合元素的过滤-filter11.4 集合元素的化简-reduce11.5 集合元素的折叠-fold11.6 集合元素的扫描-scan11.7 集合的综合应用案例11.8 集合的合并-zip11.9 集合的迭代器-iterator11.10 流-Stream11.11 视图-view11.12 线程安全的集合11.13 并行集合11.14 操作符第十二章 模式匹配12.1 match12.2 守卫12.3 模式中的变量12.4 类型匹配12.5 数组匹配12.6 列表匹配12.7 元组匹配12.8 对象匹配12.9 变量声明中的模式12.10 for表达式中的模式12.11 样例(模板)类12.12 case 语句的中置(缀)表达式12.13 匹配嵌套结构12.14 密封类


第十一章 数据结构(下)-集合操作

11.1 集合元素的映射-map

看一个实际需求
  要求:请将 List(3, 5, 7) 中的所有元素都 * 2,将其结果放到一个新的集合中返回,即返回一个新的 List(6, 10, 14), 请编写程序实现。
使用传统的方法解决
示例代码如下:

package com.atguigu.chapter11.test

/**  * 要求:请将 List(3, 5, 7) 中的所有元素都 * 2,将其结果放到一个新的集合中返回,即返回一个新的 List(6, 10, 14), 请编写程序实现。  */object MapOperateDemo01 {  def main(args: Array[String]): Unit = {    val list1 = List(3, 5, 7) // 集合    var list2 = List[Int]() // 新的集合,准备放入新的内容    for (item <- list1) { // 遍历      list2 = list2 :+ item * 2 // 对元素*2,然后加入list2集合    }    println("list2=" + list2) // List(6, 10, 14)

    // 对上面传统的方法来解决问题的小结:    // 1. 优点    //(1) 处理方法比较直接,好理解    // 2. 缺点    // (1) 不够简洁,高效    // (2) 没有体现函数式编程特点:集合 => 函数 => 新的集合 => 函数 ..    // (3) 不利于处理复杂的数据处理业务  }}

输出结果如下:

list2=List(6, 10, 14)

11.1.1 map 映射函数的操作


内存图解如下:

11.1.2 高阶函数基本使用案例1+案例2

示例代码如下:

package com.atguigu.chapter11.test

object HighOrderFunDemo01 {  def main(args: Array[String]): Unit = {    // 简言之:二阶带参函数    // 使用高阶函数(函数中有函数)=> 函数中有另一个函数的名称    // val res1 = test1(sum, 3.5) // 等价于下面形式    val res1 = test1(sum _, 3.5)    println("res1=" + res1)

    // 在 scala 中,可以把一个函数直接赋给一个变量,但是不执行函数,格式:函数名 _   注意:本质上是将内存地址赋值给栈里面的变量!!!    val f0 = myPrint1 // 赋值的同时执行无参函数    val f1 = myPrint1 _    f1() // 执行无参函数    val f2 = myPrint2 _    f2(100) // 执行带参函数    // 注意:对于一阶函数而言,函数名 或者 函数名 _ 效果是不一样的。

    // 简言之:二阶不带参函数    // test2(sayOK) // 等价于下面形式    test2(sayOK _)

    // 注意:对于高阶函数而言,函数(函数名) 或者 函数(函数名 _) 效果是一样的。  }

  // 简言之:一阶函数  def myPrint1(): Unit = {    println("hello world")  }

  def myPrint2(i: Int): Unit = {    println("hello world" + i)  }

  // 说明  // 1. test1 就是一个高阶带参函数  // 2. f: Double => Double 表示一个函数,该函数可以接受一个 Double,返回 Double  // 3. n1: Double 普通参数  // 4. f(n1) 在 test 函数中,执行 你传入的函数  def test1(f: Double => Double, n1: Double) = {    f(n1)  }

  // 普通的函数,可以接受一个 Double,返回 Double  def sum(d: Double): Double = {    d + d  }

  def test2(f: () => Unit) = {    f()  }

  def sayOK() = {    println("sayOK")  }}

输出结果如下:

res1=7.0hello worldhello worldhello world100sayOK

11.1.3 使用 map 映射函数来解决

示例代码如下:

package com.atguigu.chapter11.test

object MapOperateDemo02 {  def main(args: Array[String]): Unit = {    // 说明 list1.map(f1) 做了什么    // 1. 将 List 这个集合的元素依次遍历    // 2. 将各个元素传递给 f1 函数 => 新 Int    // 3. 将得到新 Int,放入到一个新的集合并返回    // 4. 因此 f1 函数会被调用3次    val list1 = List(3, 5, 7)    val list2 = list1.map(f1)    println(list2) // List(6, 10, 14)  }

  def f1(n: Int): Int = {    2 * n  }

}

输出结果如下:

List(6, 10, 14)

11.1.4 模拟实现 map 映射函数的机制

示例代码如下:

package com.atguigu.chapter11.test

object MapOperateDemo02 {  def main(args: Array[String]): Unit = {    // 说明 list1.map(f1) 做了什么    // 1. 将 List 这个集合的元素依次遍历    // 2. 将各个元素传递给 f1 函数 => 新 Int    // 3. 将得到新 Int,放入到一个新的集合并返回    // 4. 因此 f1 函数会被调用3次    val list1 = List(3, 5, 7)    val list2 = list1.map(f1)    println(list2) // List(6, 10, 14)

    // 模拟实现 map 映射函数的机制(固定参数个数)    val myList1 = MyList()    val myList2 = myList1.map(f1)    println(myList2) // List(6, 10, 14)

    // 模拟实现 map 映射函数的机制(可变参数)    val myList01 = new MyList01(1, 2, 3, 4)    val myList02 = myList01.map(f1)    println(myList02)  }

  def f1(n: Int): Int = {    2 * n  }}

// 自定义 List 集合class MyList {  var list1 = List(3, 5, 7)  var list2 = List[Int]()

  def map(f: Int => Int): List[Int] = {    for (item <- list1) {      // 过滤      // 扁平化      // ......      // 遍历      list2 = list2 :+ f(item)    }    list2  }}

// 伴生对象,重写 apply 方法object MyList {  def apply(): MyList = new MyList()}

class MyList01(params: Int*) {  var list02 = List[Int]()

  def map(f: Int => Int): List[Int] = {    for (item <- params) {      // 过滤      // 扁平化      // ......      // 遍历      list02 = list02 :+ f(item)    }    list02  }}

输出结果如下:

List(6, 10, 14)List(6, 10, 14)List(2, 4, 6, 8)

11.1.5 课堂练习

  请将 val names = List("Alice", "Bob", "Nick") 中的所有单词,全部转成字母大写,返回到新的 List 集合中。
示例代码如下:

package com.atguigu.chapter11.exercise

/**  * 请将 `val names = List("Alice", "Bob", "Nick")` 中的所有单词,全部转成字母大写,返回到新的 List 集合中。  */object MapExercise01 {  def main(args: Array[String]): Unit = {    val names = List("Alice", "Bob", "Nick")

    def upper(s: String): String = {      s.toUpperCase    }

    val names2 = names.map(upper)    println("names=" + names2) // names=List(ALICE, BOB, NICK)  }}

输出结果如下:

names=List(ALICE, BOB, NICK)

11.2 集合元素的扁平-flatMap

  flat 即压扁,压平,扁平化,效果就是将集合中的每个元素的子元素映射到某个函数并返回新的集合。
示例代码如下:

package com.atguigu.chapter11.test

object FlatMapDemo01 {  def main(args: Array[String]): Unit = {    val names = List("Alice", "Bob", "Nick")

    def upper( s : String ) : String = {      s. toUpperCase    }

    // 注意:每个字符串也是 char 集合    println(names.flatMap(upper)) // List(A, L, I, C, E, B, O, B, N, I, C, K)  }}

输出结果如下:

List(A, L, I, C, E, B, O, B, N, I, C, K)

11.3 集合元素的过滤-filter

  集合元素的过滤 filter:将符合要求的数据(筛选)放置到新的集合中。
  应用案例:将 val names = List("Alice", "Bob", "Nick") 集合中首字母为‘A‘的筛选到新的集合。
  注意:集合.filter(过滤函数) 过滤函数的返回值类型必须是布尔类型。
示例代码如下:

package com.atguigu.chapter11.test

object FilterDemo01 {  def main(args: Array[String]): Unit = {    val names = List("Alice", "Bob", "Nick")

    def startA(s: String): Boolean = {      s.startsWith("A")    }

    val names2 = names.filter(startA)    println("names=" + names2) // names=List(Alice)  }}

输出结果如下:

names=List(Alice)

11.4 集合元素的化简-reduce

化简介绍
  看一个需求:val list = List(1, 2, 3, 4 ,5),求出 list 的和。
  化简:将二元函数引用于集合中的函数。
  上面的问题当然可以使用遍历 list 方法来解决,这里我们使用 scala 的化简方式来完成。
示例代码如下:

package com.atguigu.chapter11.test

/**  * val list = List(1, 20, 30, 4 ,5),求出 list 的和。  */object ReduceDemo01 {  def main(args: Array[String]): Unit = {    val list = List(1, 2, 3, 4, 5)

    def sum(n1: Int, n2: Int): Int = {      n1 + n2    }

    val res1 = list.reduceLeft(sum)   // ((((1+2)+3)+4)+5) = 15    val res2 = list.reduceRight(sum)  // (1+(2+(3+(4+5)))) = 15    println("res1=" + res1)    println("res2=" + res2)

    //说明    // def reduceLeft[B >: A](f: (B, A) => B): B    // reduceLeft(f) 接收的函数需要的形式为 f: (B, A) => B): B    // reduceleft(f) 的运行规则是:从左边开始执行将得到的结果返回给第一个参数    // 然后继续和下一个元素运行,将得到的结果继续返回给第一个参数,继续...    // 即: ((((1+2)+3)+4)+5) = 15  }}

输出结果如下:

res1=15res2=15

课堂练习
示例代码如下:

package com.atguigu.chapter11.exercise

object ReduceExercise01 {  def main(args: Array[String]): Unit = {    // 1、分析下面的代码输出什么结果    val list = List(1, 2, 3, 4, 5)

    def minus(num1: Int, num2: Int): Int = {      num1 - num2    }

    println(list.reduceLeft(minus)) // -13    println(list.reduceRight(minus)) // 3 = (1-(2-(3-(4-5))))    println(list.reduce(minus)) // -13 是哪个,看源码秒懂

    // 2、使用化简的方法求出 List(3, 4, 2, 7, 5) 最小的值    val list1 = List(3, 4, 2, 7, 5)

    def min(n1: Int, n2: Int): Int = {      if (n1 < n2) n1 else n2    }

    println(list1.reduceLeft(min))  }}

输出结果如下:

-133-132

11.5 集合元素的折叠-fold

折叠介绍


应用案例
示例代码如下:

package com.atguigu.chapter11.test

object FoldDemo01 {  def main(args: Array[String]): Unit = {    // 折叠    val list = List(1, 2, 3, 4)

    def minus(num1: Int, num2: Int): Int = {      num1 - num2    }

    // 说明:折叠的理解和化简的运行机制几乎一样    // 理解 list.foldLeft(5)(minus) 理解成 list(5, 1, 2, 3, 4) list.reduceLeft(minus)    //步骤 (5-1)    //步骤 ((5-1) - 2)    //步骤 (((5-1) - 2) - 3)    //步骤 ((((5-1) - 2) - 3)) - 4 = - 5    println(list.foldLeft(5)(minus)) // -5  函数的柯里化现象:把一个函数的多个参数分散开来传递

    // 理解 list.foldRight(5)(minus) 理解成 list(1, 2, 3, 4, 5).reduceRight(minus)    // 步骤 (4 - 5)    // 步骤 (3- (4 - 5))    // 步骤 (2 -(3- (4 - 5)))    // 步骤 1- (2 -(3- (4 - 5))) = 3    println(list.foldRight(5)(minus)) // 3  }}

输出结果如下:

-53

foldLeft 和 foldRight 缩写方法分别是:/::\
示例代码如下:

package com.atguigu.chapter11.test

object FoldDemo02 {  def main(args: Array[String]): Unit = {    val list4 = List(1, 9, 2, 8)

    def minus(num1: Int, num2: Int): Int = {      num1 - num2    }

    var i6 = (1 /: list4) (minus) // 等价于 list4.foldLeft(1)(minus)    println(i6) // -19

    i6 = (100 /: list4) (minus) // 等价于 list4.foldLeft(100)(minus)    println(i6) // 80

    i6 = (list4 :\ 10) (minus) //  等价于 list4.foldRight(10)(minus)    println(i6) // -4  }}

输出结果如下:

-1980-4

11.6 集合元素的扫描-scan

扫描介绍
  扫描,即对某个集合的所有元素做 fold 操作,但是会把产生的所有中间结果放置于一个集合中保存。
应用实例
示例代码如下:

package com.atguigu.chapter11.test

object ScanDemo01 {  def main(args: Array[String]): Unit = {

    def minus(num1: Int, num2: Int): Int = {      num1 - num2    }

    // 5 (1, 2, 3, 4, 5) => (5, 4, 2, -1, -5, -10)    val i8 = (1 to 5).scanLeft(5)(minus) // IndexedSeq[Int]    println(i8) // Vector(5, 4, 2, -1, -5, -10)

    def add(num1: Int, num2: Int): Int = {      num1 + num2    }

    // 5 (1, 2, 3, 4, 5) => (5, 6, 8, 11, 15, 20)    val i9 = (1 to 5).scanLeft(5)(add) // IndexedSeq[Int]    println(i9) // Vector(5, 6, 8, 11, 15, 20)

    // (1, 2, 3, 4, 5) 5 => (20, 19, 17, 14, 10, 5)    val i10 = (1 to 5).scanRight(5)(add) // IndexedSeq[Int]    println(i10) // Vector(20, 19, 17, 14, 10, 5)  }}

输出结果如下:

Vector(5, 4, 2, -1, -5, -10)Vector(5, 6, 8, 11, 15, 20)Vector(20, 19, 17, 14, 10, 5)

11.7 集合的综合应用案例

练习1:val sentence = "AAAAAAAAAABBBBBBBBCCCCCDDDDDDD" 将 sentence 中各个字符,通过 foldLeft 存放到一个 ArrayBuffer 中。
目的:理解 foldLeft 的用法
示例代码如下:

package com.atguigu.chapter11.exercise

import scala.collection.mutable.ArrayBuffer

/**  * 练习1:val sentence = "AAAAAAAAAABBBBBBBBCCCCCDDDDDDD" 将 sentence 中各个字符,通过 foldLeft 存放到一个 ArrayBuffer 中。  * 目的:理解 foldLeft 的用法  */object Exercise01 {  def main(args: Array[String]): Unit = {    val sentence = "AAAAAAAAAABBBBBBBBCCCCCDDDDDDD"

    def putArray(arrBuf: ArrayBuffer[Char], c: Char): ArrayBuffer[Char] = {      arrBuf.append(c)      arrBuf    }

    val arrBuf = ArrayBuffer[Char]()    // 将 sentence.foldLeft(arrBuf)(putArray) 理解成 sentence(arrBuf, A, A, ..., D, D).reduceLeft(putArray)    println(sentence.foldLeft(arrBuf)(putArray))    // foldLeft(B)(f) 的运行规则是:从左边开始执行将得到的结果返回给第一个参数(注意:此时这里的第一个参数是一个集合)    // 然后继续和下一个元素运行,将得到的结果继续返回给第一个参数,继续...  }}

输出结果如下:

ArrayBuffer(A, A, A, A, A, A, A, A, A, A, B, B, B, B, B, B, B, B, C, C, C, C, C, D, D, D, D, D, D, D)

练习2:val sentence = "AAAAAAAAAABBBBBBBBCCCCCDDDDDDD" 使用映射集合,统计一句话中,各个字母出现的次数。
提示:Map[Char, Int]()
(1)使用 java 实现
示例代码如下:

package com.atguigu.chapter11.exercise;

import java.util.HashMap;import java.util.Map;

public class JavaExercise02 {    public static void main(String[] args) {        String sentence = "AAAAAAAAAABBBBBBBBCCCCCDDDDDDD";        Map<Character, Integer> charCountMap = new HashMap<>();        // 将字符串转化为字符数组        char[] cs = sentence.toCharArray();        // 遍历字符数组        for (char c : cs) { // Map 中有该键,取出该键对应的值+1后重新存入            if (charCountMap.containsKey(c)) {                Integer count = charCountMap.get(c);                charCountMap.put(c, count + 1);            } else { // Map 中没有该键,以键值对的方式存入该键(该键对应的值为1)                charCountMap.put(c, 1);            }        }        System.out.println(charCountMap);    }}

输出结果如下:

{A=10, B=8, C=5, D=7}

(2)使用 scala 的 flodLeft 折叠方式实现
示例代码如下:

package com.atguigu.chapter11.exercise

import scala.collection.mutable

/**  * 练习2:val sentence = "AAAAAAAAAABBBBBBBBCCCCCDDDDDDD" 使用映射集合,统计一句话中,各个字母出现的次数。  * 提示:Map[Char, Int]()  */object Exercise02 {  def main(args: Array[String]): Unit = {    val sentence = "AAAAAAAAAABBBBBBBBCCCCCDDDDDDD"

    // 方式一:不可变 Map,是有序的    def charCount1(map: Map[Char, Int], c: Char): Map[Char, Int] = {      // 向 Map 中添加键值对      // val map2 = map + (c -> (map.getOrElse(c, 0) + 1)) // 如果键c有返回键c对应的值并加1,键c没有返回0并加1      // map2      // 简写      map + (c -> (map.getOrElse(c, 0) + 1)) // 如果键c有,返回键c对应的值并加1,键c没有,返回0并加1    }

    val map1 = Map[Char, Int]()    println(sentence.foldLeft(map1)(charCount1)) // Map(A -> 10, B -> 8, C -> 5, D -> 7)    // 将 sentence.foldLeft(map1)(charCount) 理解成 sentence(map1, A, A, ..., D, D).reduceLeft(charCount)    // foldLeft(B)(f) 的运行规则是:从左边开始执行将得到的结果返回给第一个参数(注意:此时这里的第一个参数是一个集合)    // 然后继续和下一个元素运行,将得到的结果继续返回给第一个参数,继续...

    println("------------------------------------")

    // 方式二:可变 Map,是无序的    def charCount2(map: mutable.Map[Char, Int], c: Char): mutable.Map[Char, Int] = {      // 向 Map 中添加键值对      map += (c -> (map.getOrElse(c, 0) + 1)) // 如果键c有,返回键c对应的值并加1,键c没有,返回0并加1    }

    val map2 = mutable.Map[Char, Int]()    println(sentence.foldLeft(map2)(charCount2))  }}

输出结果如下:

Map(A -> 10, B -> 8, C -> 5, D -> 7)------------------------------------Map(D -> 7, A -> 10, C -> 5, B -> 8)

练习3:大数据中经典的 wordcount 案例。
val lines = List("atguigu han hello ", "atguigu han aaa aaa aaa ccc ddd uuu")
使用映射集合,list 中各个单词出现的次数,并按出现次数排序。
示例代码链接:xxx

11.8 集合的合并-zip

  在开发中,当我们需要将两个集合进行 对偶元组合并,可以使用拉链
示例代码如下:

package com.atguigu.chapter11.test

object ZipDemo01 {  def main(args: Array[String]): Unit = {    // 拉链    val list1 = List(1, 2, 3)    val list2 = List(4, 5, 6)    val list3 = list1.zip(list2)    println(list3) // List((1,4), (2,5), (3,6))  }}

输出结果如下:

List((1,4), (2,5), (3,6))

拉链使用的注意事项

11.9 集合的迭代器-iterator

基本说明
  通过 iterator 方法从集合获得一个迭代器,通过 while 循环和 for 表达式对集合进行遍历。(学习使用迭代器进行集合的遍历)
示例代码如下:

package com.atguigu.chapter11.test

object IteratorDemo01 {  def main(args: Array[String]): Unit = {    val iterator = List(1, 2, 3, 4, 5).iterator // 得到迭代器    /*    这里我们看看 iterator 的继承关系    def iterator: Iterator[A] = new AbstractIterator[A] {      var these = self      def hasNext: Boolean = !these.isEmpty      def next(): A =        if (hasNext) {          val result = these.head; these = these.tail; result        } else Iterator.empty.next()     */    println("----------遍历方式1 while ----------")    while (iterator.hasNext) {      println(iterator.next())    }    println("----------遍历方式2 for ----------")    for (enum <- iterator) {      println(enum)    }

  }}

输出结果如下:

----------遍历方式1 while ----------12345----------遍历方式2 for ----------12345

应用案例小结

11.10 流-Stream

基本介绍


流的应用案例
示例代码如下:

package com.atguigu.chapter11.test

object StreamDemo01 {  def main(args: Array[String]): Unit = {    // 创建 Stream    def numsForm(n: BigInt): Stream[BigInt] = n #:: numsForm(n + 1)

    val stream1 = numsForm(1)    println(stream1) // Stream(1, ?)    // 取出第一个元素    println("head=" + stream1.head) // head=1    // 使用 tail,会动态的向 stream 集合按规则生成新的元素    println(stream1.tail) // Stream(2, ?)    println(stream1) // Stream(1, 2, ?)

    // 案例:使用 map 映射 stream 的元素并进行一些计算    //创建Stream    def numsForm2(n: BigInt): Stream[BigInt] = n #:: numsForm2(n + 1)

    def multi(x: BigInt): BigInt = {      x * x    }

    println(numsForm2(5).map(multi)) // Stream(25, ?)  }}

输出结果如下:

Stream(1, ?)head=1Stream(2, ?)Stream(1, 2, ?)Stream(25, ?)

11.11 视图-view


示例代码如下:

package com.atguigu.chapter11.test

object ViewDemo01 {  def main(args: Array[String]): Unit = {    def multiple(num: Int): Int = {      num    }

    def eq(i: Int): Boolean = {      i.toString.equals(i.toString.reverse)    }

    // 没有使用 view    val viewSquares1 = (1 to 100).map(multiple).filter(eq)    println(viewSquares1)

    // 使用 view,view 方法产出一个总是被懒执行的集合    val viewSquares2 = (1 to 100).view.map(multiple).filter(eq)    println(viewSquares2)    // 遍历    for (item <- viewSquares2) {      println(item)    }    // 小结:    // 对集合进行 map, filter, reduce, fold, ...    // 你并不希望立即执行,而是在使用到结果时才执行,则可以使用 view 来进行优化(大数据优化)  }}

输出结果如下:

Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99)SeqViewMF(...)123456789112233445566778899

11.12 线程安全的集合

11.13 并行集合


示例代码如下:
1、打印1~5

package com.atguigu.chapter11.test

object ParallelDemo01 {  def main(args: Array[String]): Unit = {    // (1 to 5).foreach(println) 等价于下面    (1 to 5).foreach(println(_))

    println("----------")

    // 这里输出的结果是无序的,说明是将 println 任务分配给不同 cpu    (1 to 5).par.foreach(println(_))  }}

输出结果如下:

12345----------13524

2、查看并行集合中元素访问的线程
示例代码如下:

package com.atguigu.chapter11.test

object ParallelDemo02 {  def main(args: Array[String]): Unit = {    val result1 = (0 to 100).map{case _ => Thread.currentThread.getName}.distinct    val result2 = (0 to 100).par.map{case _ => Thread.currentThread.getName}.distinct    println(result1)    println(result2)  }}

输出结果如下:

Vector(main)ParVector(ForkJoinPool-1-worker-29, ForkJoinPool-1-worker-31, ForkJoinPool-1-worker-13, ForkJoinPool-1-worker-21, ForkJoinPool-1-worker-7, ForkJoinPool-1-worker-9, ForkJoinPool-1-worker-27, ForkJoinPool-1-worker-23, ForkJoinPool-1-worker-11, ForkJoinPool-1-worker-17, ForkJoinPool-1-worker-3, ForkJoinPool-1-worker-25)

11.14 操作符


示例代码如下:

package com.atguigu.chapter11.test

object OperatorDemo01 {  def main(args: Array[String]): Unit = {    // 案例    val n1 = 1    val n2 = 2    val r1 = n1 + n2  // 3    val r2 = n1.+(n2) // 3 看 Int 的源码即可说明

    // 应用    val monster = new Monster

    monster + 10    monster.+(10)    println("monster.money=" + monster.money) // 20

    println(monster ++)    println(monster.++)    println("monster.money=" + monster.money) // 22

    !monster    println("monster.money=" + monster.money) // -22  }}

class Monster {  var money: Int = 0

  // 对操作符进行重载(中置操作符)  def +(n: Int): Unit = {    this.money += n  }

  // 对操作符进行重载(后置操作符)  def ++(): Unit = {    this.money += 1  }

  // 对操作符进行重载(前置操作符:一元运算符)  def unary_!(): Unit = {    this.money = -this.money  }}

输出结果如下:

monster.money=20()()monster.money=22monster.money=-22

第十二章 模式匹配

12.1 match

1、基本介绍


2、Java Switch 的简单回顾

3、Scala 的 match 的快速入门案列
示例代码如下:

package com.atguigu.chapter12.mymatch

object MatchDemo01 {  def main(args: Array[String]): Unit = {    // 模式匹配,类似于 Java 的 switch 语法    // 说明    // 1. match (类似 java switch) 和 case 是关键字    // 2. 如果匹配成功,则执行 => 后面的代码块(即代码可以有多行)    // 3. 匹配的顺序是从上到下,匹配到一个就执行对应的代码    // 4. => 后面的代码块,不要写 break,会自动的退出 match    // 5. 如果一个都没有匹配到,则执行 case _ 后面的代码块    val oper = ‘#‘    val n1 = 20    val n2 = 10    var res = 0    oper match {      case ‘+‘ => res = n1 + n2      case ‘-‘ => res = n1 - n2      case ‘*‘ => res = n1 * n2      case ‘/‘ => res = n1 / n2      case _ => println("oper error")    }    println("res=" + res)

  }}

输出结果如下:

oper errorres=0

4、match 的细节和注意事项

12.2 守卫

1、基本介绍
  如果想要表达匹配某个范围的数据,就需要在模式匹配中增加条件守卫。
2、Scala 的 守卫 的快速入门案列
示例代码如下:

package com.atguigu.chapter12.mymatch

object MatchIfDemo01 {  def main(args: Array[String]): Unit = {

    for (ch <- "+-3!") { // 是对 "+-3!" 遍历      var sign = 0      var digit = 0      ch match {        case ‘+‘ => sign = 1        case ‘-‘ => sign = -1        // 特别注意:如果 case 后有 条件守卫即 if,那么这时的 _ 不是表示默认匹配,而是表示 忽略传入的ch        case _ if ch.toString.equals("3") => digit = 3        case _ if (ch > 1110 || ch < 120) => println("ch > 10")        case _ => sign = 2      }      println(ch + " " + sign + " " + digit)    }

  }}

输出结果如下:

+ 1 0- -1 03 0 3ch > 10! 0 0

3、练习题
示例代码如下:

package com.atguigu.chapter12.mymatch

object MatchExercise01 {  def main(args: Array[String]): Unit = {

    for (ch <- "+-3!") {      var sign = 0      var digit = 0      ch match {        case ‘+‘ => sign = 1        case ‘-‘ => sign = -1        // 可以有多个 默认匹配,但是后面的默认匹配无效,编译器没有报错        case _ => digit = 3        case _ => sign = 2      }      // + 1 0    - -1 0    3 0 3   ! 0 3      println(ch + " " + sign + " " + digit)    }

  }}

输出结果如下:

+ 1 0- -1 03 0 3! 0 3

示例代码如下:

package com.atguigu.chapter12.mymatch

object MatchExercise02 {  def main(args: Array[String]): Unit = {

    for (ch <- "+-3!") {      var sign = 0      var digit = 0      ch match {        case _ => digit = 3        case ‘+‘ => sign = 1        case ‘-‘ => sign = -1        // 说明..      }      // + 0 3  - 0 3   3 0 3     ! 0 3      println(ch + " " + sign + " " + digit)    }

  }}

输出结果如下:

+ 0 3- 0 33 0 3! 0 3

12.3 模式中的变量

1、基本介绍
  如果在 case 关键字后跟变量名,那么 match 前表达式的值会赋给那个变量。
2、Scala 的 模式中的变量 的快速入门案列
示例代码如下:

package com.atguigu.chapter12.mymatch

object MatchVarDemo01 {  def main(args: Array[String]): Unit = {    val ch = ‘U‘    ch match {      case ‘+‘ => println("ok~")      // 下面 case mychar 含义是 mychar = ch      case mychar => println("ok~~" + mychar)      case _ => println("ok~~~")    }

    val ch1 = ‘+‘    // 在 Scala 中 match 是一个表达式,因此可以有返回值    // 返回值就是匹配到的代码块的最后一句话的值    val res = ch1 match {      case ‘+‘ => ch1 + "hello"      case _ => println("ok~~")    }    println("res=" + res)

  }}

输出结果如下:

ok~~Ures=+hello

12.4 类型匹配

1、基本介绍
  可以匹配对象的任意类型,这样做避免了使用 isInstanceOf 和 asInstanceOf 方法。
2、Scala 的 类型匹配 的快速入门案列
示例代码如下:

package com.atguigu.chapter12.mymatch

object MatchTypeDemo01 {  def main(args: Array[String]): Unit = {    val a = 8    // 根据 a 的值来返回 obj 实例的类型    val obj = if (a == 1) 1    else if (a == 2) "2"    else if (a == 3) BigInt(3)    else if (a == 4) Map("aa" -> 1)    else if (a == 5) Map(1 -> "aa")    else if (a == 6) Array(1, 2, 3)    else if (a == 7) Array("aa", 1)    else if (a == 8) Array("aa")

    // 根据 obj 的类型来匹配并返回    val result = obj match {      case a: Int => a      case _ : BigInt => Int.MaxValue // 如果 case _ 出现在 match 中间,则表示隐藏变量名,即不使用,而不是表示默认匹配。      case b: Map[String, Int] => "对象是一个[字符串-数字]的Map集合"      case c: Map[Int, String] => "对象是一个[数字-字符串]的Map集合"      case d: Array[String] => d // "对象是一个字符串数组"  // 如果在 case 关键字后跟变量名,那么 match 前表达式的值会赋给那个变量。      case e: Array[Int] => "对象是一个数字数组"      case f: BigInt => Int.MaxValue      case y: Float => println("xxx")      case _ => "啥也不是"    }    println(result)

  }}

输出结果如下:

[Ljava.lang.String;@23223dd8

3、类型匹配注意事项

12.5 数组匹配

1、基本介绍


2、Scala 的 匹配数组 的快速入门案列
示例代码如下:

package com.atguigu.chapter12.mymatch

object MatchArrayDemo01 {  def main(args: Array[String]): Unit = {

    val arrs = Array(Array(0), Array(1, 0), Array(0, 1, 0), Array(1, 1, 0), Array(1, 1, 0, 1))    for (arr <- arrs) {      val result = arr match {        case Array(0) => "0"        case Array(x, y) => x + "=" + y        case Array(0, _*) => "以0开头和数组"        case _ => "什么集合都不是"      }      println("result = " + result)    }

    println("--------------------")

    // 给你一个数组集合,如果该数组是 Array(10, 20),请使用默认匹配,返回 Array(20, 10)    val arrs2 = Array(Array(0), Array(1, 0), Array(0, 1, 0), Array(1, 1, 0), Array(1, 1, 0, 1))

    for (arr <- arrs2 ) {      val result = arr match {        case Array(x, y) => ArrayBuffer(y, x) // Array(y, x).toBuffer        case _ => "不处理"      }      println("result = " + result)    }  }}

输出结果如下:

result = 0result = 1=0result = 以0开头和数组result = 什么集合都不是result = 什么集合都不是--------------------result = 不处理result = ArrayBuffer(0, 1)result = 不处理result = 不处理result = 不处理

12.6 列表匹配

示例代码如下:

package com.atguigu.chapter12.mymatch

object MatchListDemo01 {  def main(args: Array[String]): Unit = {

    for (list <- Array(List(88), List(0), List(1, 0), List(0, 0, 0), List(1, 0, 0))) {      val result = list match {        case x :: Nil => x // 如果要匹配 List(88) 这样的只含有一个元素的列表,并原值返回        case 0 :: Nil => "0" // List 只含有0元素        case x :: y :: Nil => x + " " + y // List 只含有两个元素        case 0 :: tail => "0 ..." // List 是以0开头的,后面任意        case _ => "something else"      }      println(result)

    }  }}

输出结果如下:

8801 00 ...something else

12.7 元组匹配

示例代码如下:

package com.atguigu.chapter12.mymatch

object MatchTupleDemo01 {  def main(args: Array[String]): Unit = {    // 如果要匹配 (10, 30) 这样任意两个元素的对偶元组,应该如何写    for (pair <- Array((0, 1), (1, 0), (10, 30), (1, 1), (1, 0, 2))) {      val result = pair match {        case (0, _) => "0 ..." // 要匹配以0打头的二元组        case (y, 0) => y // 要匹配第一个元素任意,第二个元素为0的二元组        case (x, y) => (y, x)        case _ => "other"      }      println(result)    }

  }}

输出结果如下:

0 ...1(30,10)(1,1)other

12.8 对象匹配

1、基本介绍


2、Scala 的 对象匹配 的快速入门案列
应用案例1示例代码如下:

package com.atguigu.chapter12.mymatch

object MatchObjectDemo01 {  def main(args: Array[String]): Unit = {

    // 模式匹配使用    // val number: Double = 36.0    val number: Double = Square(6.0)

    number match {      // 说明 case Square(n) 的运行的机制      // 1. 当匹配到 case Square(n)      // 2. 调用 Square 的 unapply(z: Double) z的值就是 number      // 3. 如果对象提取器 unapply(z: Double) 返回的是 Some(6),则表示匹配成功,同时将6赋给 Square(n) 的n      // 4. 如果对象提取器 unapply(z: Double) 返回的是 None,则表示匹配不成功      case Square(n) => println("匹配成功,n=" + n)      case _ => println("nothing matched")    }

  }}

object Square {  // 说明  // 1. unapply 方法是对象提取器  // 2. 接收 z: Double 类型  // 3. 返回类型是 Option[Double]  // 4. 返回的值是 Some(math.sqrt(z)) 返回z的开平方的值,并放入到 Some(x)  def unapply(z: Double): Option[Double] = {    println("unapply被调用,z=" + z)    Some(math.sqrt(z))    // None...  }  def apply(z: Double): Double = z * z}

输出结果如下:

unapply被调用,z=36.0匹配成功,n=6.0

应用案例1的小结:


应用案例2示例代码如下:

package com.atguigu.chapter12.mymatch

object MatchObjectDemo02 {  def main(args: Array[String]): Unit = {    val namesString = "Alice,Bob,Thomas" // 字符串对象的构造    namesString match {      // 当 执行 case Names(first, second, third)      // 1. 会调用 unapplySeq(str) 把 "Alice,Bob,Thomas" 传入给 str      // 2. 如果 返回的是 Some("Alice","Bob","Thomas") 分别给 (first, second, third)      //    注意:这里的返回的值的个数需要和 (first, second, third) 要一样      // 3. 如果返回的 None,表示匹配失败      case Names(first, second, third) => {        println("the string contains three people‘s names")        // 打印字符串        println(s"$first $second $third")      }      case _ => println("nothing matched")    }

  }}

object Names {  // 当构造器是多个参数时,就会触发这个对象提取器  def unapplySeq(str: String): Option[Seq[String]] = {    if (str.contains(",")) Some(str.split(",")) else None  }}

输出结果如下:

the string contains three people‘s namesAlice Bob Thomas

应用案例2的小结:

12.9 变量声明中的模式

1、基本介绍
  match 中每一个 case 都可以单独提取出来,意思是一样的。
2、Scala 中 变量声明中的模式 快速入门案列
示例代码如下:

package com.atguigu.chapter12.mymatch

object MatchVarDemo02 {  def main(args: Array[String]): Unit = {    val (x, y, z) = (1, 2, "hello") // 一次性可以定义多个变量    println("x=" + x)

    val (q, r) = BigInt(10) /% 3  // q = BigInt(10) / 3  r = BigInt(10) % 3

    val arr = Array(1, 7, 2, 9)    val Array(first, second, _*) = arr // 提出arr的前两个元素    println(first, second)  }}

输出结果如下:

x=1(1,7)

12.10 for表达式中的模式

1、基本介绍
  for循环也可以进行模式匹配。
2、Scala 中 for表达式中的模式 快速入门案列
示例代码如下:

package com.atguigu.chapter12.mymatch

object MatchForDemo01 {  def main(args: Array[String]): Unit = {    val map = Map("A" -> 1, "B" -> 0, "C" -> 3)    for ((k, v) <- map) {      println(k + " -> " + v)    }

    println("----------")    // 只遍历出 value =0 的 key-value,其它的过滤掉    for ((k, 0) <- map) { // 过滤,简洁高效      println(k + " --> " + 0)    }

    println("----------")    // 这个就是上面代码的另外写法,只是下面的用法灵活和强大    for ((k, v) <- map if v == 0) { // for 循环中的守卫      println(k + " ---> " + v)    }

  }}

输出结果如下:

A -> 1B -> 0C -> 3----------B --> 0----------B ---> 0

12.11 样例(模板)类

1、Scala 样例(模板)类 的快速入门案列
示例代码如下:

package com.atguigu.chapter12.caseclass

object CaseClassDemo01 {  def main(args: Array[String]): Unit = {    println("ok")  }}

// 说明: 这里的 Dollar, Currencry, NoAmount 是样例类。abstract class Amountcase class Dollar(value: Double) extends Amountcase class Currency(value: Double, unit: String) extends Amountcase object NoAmount extends Amount

2、基本介绍

3、样例类最佳实践1
  当我们有一个类型为 Amount 的对象时,可以用模式匹配来匹配他的类型,并将属性值绑定到变量(即:把样例类对象的属性值提取到某个变量,该功能非常有用!)
示例代码如下:

package com.atguigu.chapter12.caseclass

/**  * 1、当我们有一个类型为 Amount 的对象时,可以用模式匹配来匹配他的类型,并将属性值绑定到变量(即:把样例类对象的属性值提取到某个变量,该功能非常有用!)  */object CaseClassDemo02 {  def main(args: Array[String]): Unit = {    // 该案例的作用:体验使用样例类方式进行对象匹配简洁性    for (amt <- Array(Dollar2(1000.0), Currency2(1000.0, "RMB"), NoAmount2)) {      val result = amt match {        // 说明:即我们在使用样例类进行对象匹配的时候,不需要手写 unapply 方法了        case Dollar2(v) => "$" + v        // 说明        case Currency2(v, u) => v + " " + u        case NoAmount2 => ""      }      println(amt + ": " + result)    }

  }}

// 说明: 这里的 Dollar2, Currencry2, NoAmount2 是样例类。abstract class Amount2

case class Dollar2(value: Double) extends Amount2

case class Currency2(value: Double, unit: String) extends Amount2

case object NoAmount2 extends Amount2

输出结果如下:

Dollar2(1000.0): $1000.0Currency2(1000.0,RMB): 1000.0 RMBNoAmount2: 

4、样例类最佳实践2
  样例类的 copy 方法和带名参数,copy 可以创建一个与现有对象值相同的新对象,并可以通过带名参数来修改某些属性。
示例代码如下:

package com.atguigu.chapter12.caseclass

/**  * 2、样例类的 copy 方法和带名参数,copy 可以创建一个与现有对象值相同的新对象,并可以通过带名参数来修改某些属性  */object CaseClassDemo03 {  def main(args: Array[String]): Unit = {    val amt = Currency3(29.95, "RMB")    val amt1 = amt.copy() // 创建了一个新的对象,属性值和上面一样    val amt2 = amt.copy(value = 19.95)  // 创建了一个新对象,但是修改了value属性    val amt3 = amt.copy(unit = "英镑")  // 创建了一个新对象,但是修改了unit属性    println(amt)    println(amt1)    println(amt2)    println(amt3)  }}

// 说明: 这里的 Dollar3, Currencry3, NoAmount3 是样例类。abstract class Amount3

case class Dollar3(value: Double) extends Amount3

case class Currency3(value: Double, unit: String) extends Amount3

case object NoAmount3 extends Amount3

输出结果如下:

Currency3(29.95,RMB)Currency3(29.95,RMB)Currency3(19.95,RMB)Currency3(29.95,英镑)

12.12 case 语句的中置(缀)表达式

1、基本介绍
  什么是中置表达式?
  答:1 + 2,这就是一个中置表达式。如果 unapply 方法产出一个元组,你可以在 case 语句中使用中置表示法。比如:可以匹配一个 List 序列。
2、快速入门案列
示例代码如下:

package com.atguigu.chapter12.mymatch

object MidCaseDemo01 {  def main(args: Array[String]): Unit = {

    List(1, 3, 5, 9) match { // 修改并测试      // 1.两个元素间::叫中置表达式,至少first,second两个匹配才行。      // 2.first 匹配第一个,second 匹配第二个,rest 匹配剩余部分 (5, 9)      case first :: second :: rest => println(first + " " + second + " " + rest.length + " " + rest) // 1 3 2 List(5, 9)      case _ => println("匹配不到...")    }

  }}

输出结果如下:

1 3 2 List(5, 9)

12.13 匹配嵌套结构

1、基本介绍
  匹配嵌套的操作原理类似于正则表达式。
2、匹配嵌套结构 的最佳实践案例-商品捆绑打折出售
现在有一些商品,请使用 Scala 设计相关的样例类,完成商品捆绑打折出售。要求:
  1、商品捆绑可以是单个商品,也可以是多个商品。
  2、打折时按照折扣x元进行设计。
  3、能够统计出所有捆绑商品打折后的最终价格。
创建样例类

// 先设计样例类abstract class Item // 项

// 商品,以书籍为例case class Book(description: String, price: Double) extends Item

// 商品,以食品为例// 商品,以酒水为例...

// Bundle 捆绑类case class Bundle(description: String, discount: Double, item: Item*) extends Item

匹配嵌套结构(就是 Bundle 的对象)

    // 具体的打折案例表示:有一捆书,漫画(一本)(40-10) + 文学作品(两本)(80+30-20) = 30 + 90 = 120.0    val sale = Bundle("书籍", 10, Book("漫画", 40), Bundle("文学作品", 20, Book("《阳关》", 80), Book("《围城》", 30)))

为了讲解案列,补充三个新的知识点:
知识点1-将 desc 绑定到第一个 Book 的描述。


知识点2-通过 @ 表示法将嵌套的值绑定到变量。* 绑定剩余 Item 到 rest。

知识点3-不使用
* 绑定剩余 Item 到 rest。

3个知识点的所有示例代码如下:

package com.atguigu.chapter12.caseclass

object SalesDem01 {  def main(args: Array[String]): Unit = {    // 具体的打折案例表示:有一捆书,漫画(一本)(40-10) + 文学作品(两本)(80+30-20) = 30 + 90 = 120.0    val sale = Bundle("书籍", 10, Book("漫画", 40), Bundle("文学作品", 20, Book("《阳关》", 80), Book("《围城》", 30)))

    // 知识点1:取出这个嵌套结构中的 "漫画"的描述    val res = sale match  {      // 如果我们进行对象匹配时,不想接受某些值,则使用_ 忽略即可,_* 表示忽略所有。      case Bundle(_, _, Book(desc, _), _*) => desc    }    println("res=" + res)

    // 知识点2:如何将 "漫画" 和 这个嵌套结构中的 "漫画" 和 紫色的部分 绑定到变量,即赋值到变量中。    val res2 = sale match {      case Bundle(_, _, art @ Book(_, _), rest @ _*) => (art, rest)    }    println("art=" + res2._1)    println("rest=" + res2._2)

    // 知识点3:如何将 "漫画" 和 这个嵌套结构中的 "漫画" 和 紫色的部分 绑定到变量,即赋值到变量中。明确说明没有多个 Bundle。    val res3 = sale match {      case Bundle(_, _, art @ Book(_, _), rest) => (art, rest) // rest 等价于 rest @ _    }    println("art=" + res3._1)    println("rest=" + res3._2)

    // 匹配嵌套案例完成    def price(it: Item): Double = {      it match {        case Book(_, price) => price        // 生成一个新的集合,_是将 its 中每个循环的元素传递到 price 中 it 中。递归操作        case Bundle(_, disc, its @ _*) => its.map(price).sum - disc      }    }    println(price(sale))  }}

// 先设计样例类abstract class Item // 项

// 商品,以书籍为例case class Book(description: String, price: Double) extends Item

// 商品,以食品为例// 商品,以酒水为例...

// Bundle 捆绑类case class Bundle(description: String, discount: Double, item: Item*) extends Item

输出结果如下:

res=漫画art=Book(漫画,40.0)rest=WrappedArray(Bundle(文学作品,20.0,WrappedArray(Book(《阳关》,80.0), Book(《围城》,30.0))))art=Book(漫画,40.0)rest=Bundle(文学作品,20.0,WrappedArray(Book(《阳关》,80.0), Book(《围城》,30.0)))120.0

12.14 密封类

1、基本介绍


2、密封类卫 的快速入门案列

原文地址:https://www.cnblogs.com/chenmingjun/p/10643475.html

时间: 2024-11-05 23:02:01

大数据技术之_16_Scala学习_08_数据结构(下)-集合操作+模式匹配的相关文章

大数据技术之_16_Scala学习_11_客户信息管理系统+并发编程模型 Akka+Akka 网络编程-小黄鸡客服案例+Akka 网络编程-Spark Master Worker 进程通讯项目

第十五章 客户信息管理系统15.1 项目的开发流程15.2 项目的需求分析15.3 项目的界面15.4 项目的设计-程序框架图15.5 项目的功能实现15.5.1 完成 Customer 类15.5.2 完成显示主菜单和退出软件功能15.5.3 完成显示客户列表的功能15.5.4 完成添加客户的功能15.5.5 完成删除客户的功能15.5.6 完善退出确认功能15.5.7 完善删除确认功能15.5.8 完成修改客户的功能第十六章 并发编程模型 Akka16.1 Akka 的介绍16.2 Acto

大数据技术之_20_Elasticsearch学习_01_概述 + 快速入门 + Java API 操作 + 创建、删除索引 + 新建、搜索、更新删除文档 + 条件查询 + 映射操作

一 概述1.1 什么是搜索?1.2 如果用数据库做搜索会怎么样?1.3 什么是全文检索和 Lucene?1.4 什么是 Elasticsearch?1.5 Elasticsearch 的适用场景1.6 Elasticsearch 的特点1.7 Elasticsearch 的核心概念1.7.1 近实时1.7.2 Cluster(集群)1.7.3 Node(节点)1.7.4 Index(索引 --> 数据库)1.7.5 Type(类型 --> 表)1.7.6 Document(文档 -->

大数据技术之_08_Hive学习_01_Hive入门+Hive安装、配置和使用+Hive数据类型

第1章 Hive入门1.1 什么是Hive1.2 Hive的优缺点1.2.1 优点1.2.2 缺点1.3 Hive架构原理1.4 Hive和数据库比较1.4.1 查询语言1.4.2 数据存储位置1.4.3 数据更新1.4.4 索引1.4.5 执行1.4.6 执行延迟1.4.7 可扩展性1.4.8 数据规模第2章 Hive安装.配置和使用2.1 Hive安装地址2.2 Hive安装部署2.3 将本地文件导入Hive案例2.4 MySql安装2.4.1 安装包准备2.4.2 安装MySql服务器2.

大数据技术之_19_Spark学习_05_Spark GraphX 应用解析 + Spark GraphX 概述、解析 + 计算模式 + Pregel API + 图算法参考代码 + PageRank 实例

第1章 Spark GraphX 概述1.1 什么是 Spark GraphX1.2 弹性分布式属性图1.3 运行图计算程序第2章 Spark GraphX 解析2.1 存储模式2.1.1 图存储模式2.1.2 GraphX 存储模式2.2 vertices.edges 以及 triplets2.2.1 vertices2.2.2 edges2.2.3 triplets2.3 图的构建2.3.1 构建图的方法2.3.2 构建图的过程2.4 计算模式2.4.1 BSP 计算模式2.4.2 图操作一

大数据技术之_03_Hadoop学习_02_入门_Hadoop运行模式+【本地运行模式+伪分布式运行模式+完全分布式运行模式(开发重点)】+Hadoop编译源码(面试重点)+常见错误及解决方案

第4章 Hadoop运行模式4.1 本地运行模式4.1.1 官方Grep案例4.1.2 官方WordCount案例4.2 伪分布式运行模式4.2.1 启动HDFS并运行MapReduce程序4.2.2 启动YARN并运行MapReduce程序4.2.3 配置历史服务器4.2.4 配置日志的聚集4.2.5 配置文件说明4.3 完全分布式运行模式(开发重点)4.3.1 虚拟机准备4.3.2 编写集群分发脚本xsync4.3.3 集群配置4.3.4 集群单点启动4.3.5 SSH无密登录配置4.3.6

大数据技术之_19_Spark学习_02_Spark Core 应用解析+ RDD 概念 + RDD 编程 + 键值对 RDD + 数据读取与保存主要方式 + RDD 编程进阶 + Spark Core 实例练习

第1章 RDD 概念1.1 RDD 为什么会产生1.2 RDD 概述1.2.1 什么是 RDD1.2.2 RDD 的属性1.3 RDD 弹性1.4 RDD 特点1.4.1 分区1.4.2 只读1.4.3 依赖1.4.4 缓存1.4.5 CheckPoint第2章 RDD 编程2.1 RDD 编程模型2.2 RDD 创建2.2.1 由一个已经存在的 Scala 集合创建,即集合并行化(测试用)2.2.2 由外部存储系统的数据集创建(开发用)2.3 RDD 编程2.3.1 Transformatio

大数据技术之_08_Hive学习_04_压缩和存储(Hive高级)+ 企业级调优(Hive优化)

第8章 压缩和存储(Hive高级)8.1 Hadoop源码编译支持Snappy压缩8.1.1 资源准备8.1.2 jar包安装8.1.3 编译源码8.2 Hadoop压缩配置8.2.1 MR支持的压缩编码8.2.2 压缩参数配置8.3 开启Map输出阶段压缩8.4 开启Reduce输出阶段压缩8.5 文件存储格式8.5.1 列式存储和行式存储8.5.2 TextFile格式8.5.3 Orc格式8.5.4 Parquet格式8.5.5 主流文件存储格式对比实验8.6 存储和压缩结合8.6.1 修

大数据技术之_09_Hive学习_复习与总结

一.知识梳理1.1.背景表结构1.1.1.order by1.1.2.sort by1.1.3.distribute by1.1.4.cluster by1.2.行转列.列转行(UDAF 与 UDTF)1.2.1.行转列1.2.2.列转行1.3.建表时的数组操作1.4.orc 存储1.5.Hive 分桶1.5.1.直接分桶1.5.2.在分区中分桶二.总结2.1 启动/停止hadoop集群.zookeeper集群.历史服务器2.2 访问hive的两种方式2.3 CentOS6x与Cenos7x命令

大数据技术之_19_Spark学习_02_Spark Core 应用解析小结

1.RDD 全称 弹性分布式数据集 Resilient Distributed Dataset它就是一个 class. abstract class RDD[T: ClassTag](    @transient private var _sc: SparkContext,    @transient private var deps: Seq[Dependency[_]]  ) extends Serializable with Logging { 继承了 Serializable 和具有 L