scala笔记

scala

http://plugins.jetbrains.com
maven:https://mvnrepository.com/
官网: www.scala-lang.org
1.scala是什么?
Scala是一门多范式的编程语言,
一种类似java的编程语言 [1] ,
设计初衷是实现可伸缩的语言 [2] 、
并集成面向对象编程和函数式编程的各种特性。
注意:
1.多范式 :面向对象、面向过程、泛型、函数式
2.面向对象编程和函数式编程【scala优点】
3.函数式:
参数: 基本数据类型、引用数据类型
参数:function【方法 函数】
4.scala运行在jvm上的 【scala 可以兼容java程序】
5.scala怎么产生的?
基于java语言开发而来的
6. java: xxx.class
xxx.java => 生成字节码文件 =》运行
xxx.scala => 生成字节码文件 => 运行
7.发明者 martin 编译器爱好者
java + 函数式编程 =》
1.pizza
2.scala
java:
jdk1.5 泛型、增强for、自动类型转换 包装 =》pizza
jdk1.8 类型推断 lambda =》 scala
2.为什么要学习scala?
1.Spark =》 scala、java、python
2.flink =》 scala、java 、python
3.开发效率高、开发简单 容易
4.scala 和 java代码 可以相互调用
3.scala版本如何选择?
1.scala :
3.x
2.x
Spark版本来决定用户使用scala的版本 :
spark3.x: scala 2.12/2.13 2.11用不了
spark2.x: scala 2.11/2.12
scala: 2.12.14
scala开发入门:
1.main方法 是整个scala应用程序的入口点
2.scala代码是以.scala结尾的
3.scala代码每行结束 不需要以;结尾
4.一行一个代码语句 最好不要一行写多个代码语句

基本语法

1.值 val
val 变量名:数据类型 = 值 val 不可变的
2.变量 var
var 变量名:数据类型 = 值 var 可变的
类型推断: 通过 变量值 推断出来的
3.变量与值 的初始化
1.显示初始化
2.占位符 : _
val name:String=_
注意:
占位符这种方式 前提 一定要明确是什么数据类型 进行站位
场景:
定义类 属性使用的
4.数据类型
1.常用的数据类型:
字符串:String
数值:Int、Long、Float、Double
布尔:Boolean
2.数据类型转换 与判断
asInstanceOf[T] 数据类型转换
toxxx: A.toxx => xx

 	val num1: Int = 1
    val num2: Double = 1.1
    println(num2.toInt)
    var name:String=_

isInstanceOf[T] 判断是某种数据类型
scala跟Java不同 没有包装类
3.scala顶层数据接口
Any =》 java Object
1.AnyVal 值类型:
Unit =》 void
2.AnyRef 引用类型
String
Nothing:
值:Nothing
引用:Null =》Nothing
5.集合
常用:
Array
Range和数组差不多
List
Seq 序列 Set Map
5.1 快速构建集合的方法
to和until返回值是range:
1.to [] 左闭右闭 1-10
2.until [) 左闭右开 1-9
scala api 方法:
1.方法调用:
xxx.method
xxx method(按空格也能调用)
6.流程控制:
1.分支结构
java:
1.if else
2.switch case
scala:
1.if else

var score=80
    if (score >= 90 || score != 20){
      println("优秀")
    } else if (score >= 60){
      println("良")
    } else {
      println("差")
    }
		2.模式匹配
2.循环: 
	for while 算子[高级api]
	for(item <-数组/集合/表达式)
	scala没有三目运算符: xxx?x:y
	val arr: Array[Int] = Array(1, 2, 3, 4, 5)
    val iterator = arr.toIterator
    while (iterator.hasNext){
      val item: Int = iterator.next()
      println(item)
    }
    println("===================================")
    for (elem <- arr) {
      println(elem)
    }
    println("===================================")
    arr.foreach(println(_))

7.方法与函数
def 定义方法
val 定义函数
函数:本质就是一种特殊的方法
7.1方法
语法结构:
def 方法名(参数名:参数类型):返回值类型={方法体}

val i: Int = sum(10, 20)
    println(i)
sum1(1,2)
def sum(num1:Int,num2:Int):Int={
    num1+num2
  }
def sum1(num1:Int,num2:Int)={
    val res=num1+num2
    println(res)
  }

def :关键字
sum:方法的名字
num1:Int,num2:Int : 方法的入参
Int: 方法的返回值类型
注意:
1.scala里面 默认方法体的最后一行 作为该方法的返回值 不需要写return ,但是可以写return
2.方法返回值类型可以不写 可以进行类型推断
7.2函数
函数的本质是方法
把方法的东西进行省略:省略 方法名 +关键字 +返回值类型

def sum(num1:Int,num2:Int):Int={
	num1 + num2
}
=(num1:Int,num2:Int)={
	num1 + num2
}
=val f1=(num1:Int,num2:Int) => (num1 + num2)
val i1: Int = f1(3, 4)
println(i1)
val f1 = (num1:Int,num2:Int) => ( num1+num2 )

7.3方法入参
1.默认参数 :
注意:如果有多个参数,默认参数一定要放到 最后位置
2.可变参数:
注意:如果有多个参数,可变参数一定要放到 最后位置

defaultParm("hello")
defaultParm()
defaultParm01(10)
defaultParm01(10,"tom")
size(1,2,3,4)
size02("可变参数",1,2,3)
val array = Array(1, 2, 3, 4, 5)
size02("可变参数",array:_*)
def defaultParm(parm:String="default")={
    println(parm)
  }
def defaultParm01(p1:Int,parm:String="default")={
    println("age:"+p1+"=>"+parm)
  }
def size(num:Int*)={
    println(num.size)
  }
def size02(t:String,num:Int*)={
    println(t+"=>"+num.size)
  }

基本语法

1.普通类

def main(args: Array[String]): Unit = {
    val dl: DL2262 = new DL2262
    dl.name="tom"
    println(dl.age)
    dl.listening("Ma")
    dl.test()
  }
  class DL2262{
    var name:String=_
    val age:Int=20
    private val gender:String="nan"
    def test()={
      println(gender)
    }
    def listening (teacher:String) = {
      println(name+" is listening class of "+teacher)
    }
  }

2.伴生类和伴生对象
class 名称 是 object的伴生类 class A
object 名称 是 class的伴生对象 object A
总结:
1. 基本使用
class A =》 java 普通类一样
object A =》 java 静态类
2.常用的操作 :
apply() 方法 !!
往往使用:
object A: apply() =》 new class A

 def main(args: Array[String]): Unit = {
    // 伴生类实例化
    val a: A = new A
    a.f01()
    // 伴生对象实例化
    A.f01()
  }
  class A{
    def f01()={
      println("class A ...")
    }
  }
  object A{
    def f01()={
      println("object A...")
    }
  }
def main(args: Array[String]): Unit = {
    /**
     * 检验实例化版伴生对象会不会触发apply方法
     */
    val test: applyTest = applyTest()
    test.apply()
    val test1: applyTest = new applyTest()
    test1.apply()
  }
  class applyTest{
    def apply()= {
      println("class apply")
    }
  }
  object applyTest{
    def apply(): applyTest = {
      println("object apply")
      new applyTest()
    }
  }

3.构造器
1.主构造器
class 类名(参数列表)
参数列表:=》 参数名:参数类型
2.附属构造器
def this(参数列表) :
每个附属构造器的第一行 必须调用主构造器或者 其他的附属构造器

def main(args: Array[String]): Unit = {
    val p1: Person = new Person("杨鸣", 33)
    p1.job="jiaolian"
    println(p1.name+"\t"+p1.age+"\t"+p1.job)
    val p2: Person = new Person("马龙", 30, "乒乓球")
    println(p2.name+"\t"+p2.age+"\t"+p2.team)
  }
  class Person(val name:String,val age:Int){
    var job:String=_
    var team:String=""
    def this(name:String,age:Int,team:String){
      this(name,age)
      this.team=team
    }
  }

4.继承

def main(args: Array[String]): Unit = {
    /**
     * 实例化B是先触发父类里面构造器,再触发子类构造器
     */
    val p1: B = new B("tom", "男")
    println(p1.gender)
    println(p1.age)
    p1.f01("尘缘")
    p1.f02("喜卷长安城")
  }
  class A(name:String){
    println("进入父类构造器")
    val age:Int=10
    def f01(parm:String): Unit ={
      println(parm+"\t"+name)
    }
    println("退出父类构造器")
  }
  class B(name:String,val gender:String) extends A(name){
    println("进入子类构造器")
    def f02(parm:String): Unit ={
      println(parm+"\t"+name)
    }
    println("退出子类构造器")
  }

5.抽象类 不能new

def main(args: Array[String]): Unit = {
    val p: Person = new p1
    p.dosomeing
  }
  abstract class Person{
    def dosomeing
    def f01
    def f02
    val name:String
  }
  class p1 extends Person{
    override def dosomeing: Unit = {
      println("看了你的名字")
    }
    override def f01: Unit = {

    }
    override def f02: Unit = {

    }
    override val name: String = "zhangsan"
  }

6.特质=》接口
抽象类和特质都用extends来实现
多继承用extends A with B with C

trait TestMethod {
  val name:String=""
  def sum(num1:Int,num2:Int)={
    num1+num2
  }
  def f1
  def f2
object T7 extends TestMethod {
  def main(args: Array[String]): Unit = {
    println(sum(1, 2))
  }

  override def f1: Unit = {

  }

  override def f2: Unit = {

  }
}

7.集合
scala 集合包: scala.collection
1.长度可变
2.长度不可变
Array:
1.定长数组 =》 不可变 Array
2.变长数组 =》 可变 ArrayBuffer
1.长度不可变
Array:
1.new
2.不new
1.基本使用:
1.创建
2.赋值
3.取值
2.遍历
for
3.api :
1.元素反转
reverse [官方提供好的 api]
2.数组相加
++ 表示 类似的数据结构进行拼接
3.常见api:
max、min、sum
4.把数组内元素 转换成string的方式进行输出
String: mkString

def main(args: Array[String]): Unit = {
    val array: Array[String] = new Array[String](3)
    array(0)="zhangsan"
    array(1)="lis"
    println(array.length)
    println(array(0))
    println("=====================")
    val array1: Array[Any] = Array("1", 2, '3')
    for (elem <- array1) {
      println(elem)
    }
    println("=====================")
    for(i <- 0 until array1.length){
      println(array1(i))
    }
    println("======================")
    array1.foreach(println(_))
    println("=======================")
    array1.indices.map(i => {
      println(array1(i))
    })
    println("=======================")
    val array2: Array[Any] = array1.reverse
    for (elem <- array2) {
      println(elem)
    }
    println("========================")
    for(i <- array1.length -1 to 0 by -1){
      println(array1(i))
    }
    println("=========================")
    for(i <- (array1.length -1).to(0,-1)){
      println(array1(i))
    }
    println("==========================")
    val arr1: Array[Int] = Array(1, 2)
    val arr2: Array[Int] = Array(3, 4)
    val arr3: Array[Int] = arr1 ++ arr2
    arr3.foreach(println(_))
    println("==========================")
    println(arr3.max)
    println(arr3.min)
    println(arr3.sum)
    println("============================")
    println(arr3.mkString)
    println(arr3.mkString(","))
    println(arr3.mkString("{", ",", "}"))
  }

2.变长数组 ArrayBuffer

	val ab: ArrayBuffer[Int] = ArrayBuffer[Int]()
    println("长度:"+ab.length)
    ab +=1
    ab +=(2,3,4)
    ab ++=Array(5,6)
    for(i <- 0 until ab.length){
      println(ab(i))
    }
    println("第一个元素是:"+ab(0))
    ab(0)=10
    for (elem <- ab) {
      println(elem)
    }
    ab.insert(1,9,8,7)
    ab.foreach(println(_))
    println("==============")
    ab.remove(0)
    ab.indices.map(i =>{
      println(ab(i))
    })
    ab.remove(0,3)
    ab.indices.map(i =>{
      println(ab(i))
    })

高阶函数

函数:

 def main(args: Array[String]): Unit = {
    test01()
    test02()
  }
  /**
   * 函数的定义:val/var 函数名称 = (参数列表) =>{方法体}
   * 方法体里面只有一句语句时{}可省
   * 函数的定义:val/var 函数名称:(入参类型)=> 返回值类型 = (参数列表) =>{方法体}
   */
  def test01()={
    val f1 = (x:Int,y:Int) => x+y
    println(f1(10, 20))
  }
  def test02() = {
    val f2:(Int,Int)=>Int =(x,y)=>x+y
    println(f2(1, 2))
  }

函数 是特殊的一种方法
方法 是特殊的一种函数
他们之间可以进行相互转换

def main(args: Array[String]): Unit = {
    test01()
    test02()
    test03()
    test04()
    test05()
  }
  def test05()={
    def cal(a:Int,b:Int,op:(Int,Int)=>Int)={
      op(a,b)
    }

    println(cal(10, 20, (x, y) => x + y))
    println(cal(10, 20, _+_))//入参在后面只用到了一次就可以用简写
    println(cal(10, 20, _-_))
    println(cal(10, 20, _*_))
    println(cal(10, 20, _/_))
  }
  def test04()={
    val a =() => println("dl2262...")
    def foo(f:()=>Unit): Unit ={
      f()
    }
    foo(a)
    foo(() => println("scala"))
  }
  /**
   * 函数的定义:val/var 函数名称 = (参数列表) =>{方法体}
   * 方法体里面只有一句语句时{}可省
   * 函数的定义:val/var 函数名称:(入参类型)=> 返回值类型 = (参数列表) =>{方法体}
   */
  def test01()={
    val f1 = (x:Int,y:Int) => x+y
    println(f1(10, 20))
  }
  def test02() = {
    val f2:(Int,Int)=>Int =(x,y)=>x+y
    println(f2(1, 2))
  }
  def test03()={
    def hello(name:String)={
      println(name)
    }
    val helloFunc = hello _
    helloFunc("zhangsan")
    def add(x:Int,y:Int)=x+y
    val f3: (Int, Int) => Int = add _
    println(f3(4, 5))
    println(add(4, 5))
    // 定义一个方法,方法的参数是函数
    def foo(f4:(Int,Int) => Int)={
      f4(10,30)
    }
    println(foo(f3))
  }

高阶函数:
1.map 映射 一一映射

def main(args: Array[String]): Unit = {
    val array: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7)
    // val array1: Array[Int] = array.map((x: Int) => x * 2)
    // val array1: Array[Int] = array.map((x) => x * 2)
    // val array1: Array[Int] = array.map(x => x * 2)
    val array1: Array[Int] = array.map(_ * 2)
    array1.indices.map(i =>{
      println(array1(i))
    })
    println("=====================")
    val array2: Array[Int] = array.map(_ * 3)
    for(i<- 0 until array2.length){
      println(array2(i))
    }
def main(args: Array[String]): Unit = {
    val list: List[String] = List("HELLO", "FLINK", "TOM")
    val list1: List[String] = list.map(_ + "scale")
    list1.foreach(println(_))
    val list2: List[String] = list.map(_.toLowerCase)
    for (elem <- list2) {
      println(elem)
    }

2.tuple 元组
(1)创建
val a = (1,2,3,4) 最多能够容纳22个元素

 	val tuple: (Int, Int, Int, Int) = (1, 2, 3, 4)
    val tuple1: (Int, Int) = Tuple2(1, 2)

(2)取值
a._1 访问元组元素 下标从1 开始

	println(tuple._1)
    println(tuple1._2)

需求:
val arr = List(Array((“zs”,30),(“ls”,28)),Array((“ww”,30),(“zl”,28)))
把每个人的年龄 + 2

val arr: List[Array[(String, Int)]] = List(Array(("zs", 30), ("ls", 28)), Array(("ww", 30), ("zl", 28)))
    val list: List[Array[(String, Int)]] = arr.map(x => x.map(t => (t._1, t._2 + 2)))

3.foreach 遍历/输出 :
1.打印到控制台
2.mysql

val arr = List(1,2,3,4)		
arr.foreach(x=> println(x))
arr.foreach(println(_))

4.filter 有返回值
过滤 : 满足条件的数据 过滤出来 true false
过滤出大于3的偶数

 	val arr2 = List(1,2,3,4,5,6,7,8)
    val ints: List[Int] = arr2.map(x => x * 2).filter(x => x > 4)
    val ints1: List[Int] = arr2.filter(x => x % 2 == 0 && x > 3)
    val ints2: List[Int] = arr2.filter(_ % 2 == 0).filter(_ > 3)

需求:
val list = List(1,“张三”,2,true,3,4)
取出数值类型的数据,每个元素 * 10

	val list1 = List(1, "张三", 2, true, 3, 4)
    val ints3: List[Int] = list1.filter(x => x.isInstanceOf[Int]).map(x => x.asInstanceOf[Int]).map(x => x * 10)

5.flatMap = flatten + map 一一映射
flatMap 与map 区别:
flatMap 会"打破原来数据的 数据结构" map 不会
“打破原来数据的 数据结构” => 递归 “压扁操作”
需求:把每行数据按照 逗号进行分割 并提取出来
val arr = Array(“hello,scala,spark,flink”,“i,am,ok,doublehappy”)
split会多形成一层Array

 	val arr3 = Array("hello,scala,spark,flink","i,am,ok,doublehappy")
    val array1: Array[String] = arr3.flatMap(line => line.split(","))

6.reduce
归约 :将指定的业务逻辑 作用 两两的数据上去
先对元素1 和元素2 做操作 再将结果 对元素3做操作形成新的结果
(x,y)=>x+y:
x 表示第一个元素
y 表示下一个元素
reduce算子 =》底层走的是reduceLeft 从左面开始聚合
reduceRight

val arr4 = Array(1,2,3,4,5,6,7,8)
    arr4.reduce((x,y) => x+y)
    arr4.reduce((x,y) => {
      println(x,y)
      x+y
    })
    arr4.reduceRight((x,y) => {
      println(x,y)
      x+y
    })

7.groupBy 自定义分组 会形成Map[k,v]

	val arr5 = Array(("a",100),("b",10),("c",15),("d",20),("d",10))
    val map: Map[String, Array[(String, Int)]] = arr5.groupBy(x => x._1)
    val map1: Map[Int, Array[(String, Int)]] = arr5.groupBy(x => x._2)

8.mapValues 一一映射 返回一个Map
1.map作用在value上的
2.数据必须是kv数据类型【Map键值对 】
Map:val a = Map(“zhangsan”->24,“lisi”->18)

	val arr5 = Array(("a",100),("b",10),("c",15),("d",20),("d",10))
    val map: Map[String, Array[(String, Int)]] = arr5.groupBy(x => x._1)
    val map2: Map[String, Int] = map.mapValues(value => value.map(v => v._2).sum)

9.sortBy Map类型不能用,List或者Array可以

	val arr6 = Array(1,4,10,2)
    val array2: Array[Int] = arr6.sortBy(x => x)
    val array3: Array[Int] = arr6.sortBy(x => -x)

案例: wordcount案例 :

def main(args: Array[String]): Unit = {
    val lines = Array("linux,shell,mysql,hadoop","linux,shell,mysql,hadoop,hive,flume,kafka,scala,html,xxl","javase,html,xxl,kafka,scala")
    // 每行数据拆分成每个单词  line=>words
    val words: Array[String] = lines.flatMap(x => x.split(","))
    // words => word,1
    val word2one: Array[(String, Int)] = words.map(word => (word, 1))
    // 自定义分组  word,<1,1,1,>
    val groupbyData: Map[String, Array[(String, Int)]] = word2one.groupBy(kv => kv._1)
    // 按照word 对values求和
    val word2cnt: Map[String, Int] = groupbyData.mapValues(values => values.map(v => v._2).sum)
    // 结果按照单词的次数降序排列
    val result: List[(String, Int)] = word2cnt.toList.sortBy(value => -value._2)
    result.foreach(println(_))
  }

10.字符串插值 scala python shell

	val hello: String = "hello"
    val str: String = hello + " scala"
    println(str)
    println(s"xxx_${str}")
    val mes =
      s"""
        |这是一个多行字符串,
        |hello,
        |${str}
        |""".stripMargin
    println(mes)

11.集合
(1).List
长度不可变: List
长度可变:ListBuffer
Nil 是不可变的size为0的List :: 添加元素
head: 取出List的第一个元素
tail: 取出List的非第一个元素意外的所有

scala> Nil
res14: scala.collection.immutable.Nil.type = List()

scala> val a = 1::Nil
a: List[Int] = List(1)

scala> val b = (1,2,3)::Nil
b: List[(Int, Int, Int)] = List((1,2,3))

scala> b(0)
res15: (Int, Int, Int) = (1,2,3)

scala> val l1 = List(1,2,3,4,5)
l1: List[Int] = List(1, 2, 3, 4, 5)

scala> l1.head
res16: Int = 1

scala> l1.tail
res17: List[Int] = List(2, 3, 4, 5)

需求: 使用scala实现 求和的方法 ?

def main(args: Array[String]): Unit = {
    println(sum(1, 2, 3, 4))
    println(sum(Array(1, 2, 3): _*))
  }
  // 求和
  /**
   * 使用递归方法,方法的返回值一定要指定,否则会报错
   * @param nums
   * @return
   */
  def sum(nums:Int*):Int={
    if (nums.length==0){
      0
    } else{
      nums.head + sum(nums.tail:_*)
    }
  }

变长ListBuffer:

scala> val l1 = ListBuffer[Int]()
l1: scala.collection.mutable.ListBuffer[Int] = ListBuffer()

scala> l1 +=1
res18: l1.type = ListBuffer(1)

scala> l1 +=2
res19: l1.type = ListBuffer(1, 2)

scala> l1 +=(3,4,5)
res20: l1.type = ListBuffer(1, 2, 3, 4, 5)

scala> l1 ++=List(6,7,8)
res21: l1.type = ListBuffer(1, 2, 3, 4, 5, 6, 7, 8)

scala> l1.toList
res22: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8)

(2)Set: 无序 不可重复的 集合 【可以用于去重 】

scala> val a = List(1,1,2,2,3,3,4,4)
a: List[Int] = List(1, 1, 2, 2, 3, 3, 4, 4)

scala> val b = Set(1,1,2,2,3,3,4,4)
b: scala.collection.immutable.Set[Int] = Set(1, 2, 3, 4)

(3)Map (kv)
1.值不可变
2.值可变
1.值不可变
Option: 要么有要么无
Some => 有
None =》 无

scala> val m = Map("zhangsan" -> 13,"lisi" -> 14)
m: scala.collection.immutable.Map[String,Int] = Map(zhangsan -> 13, lisi -> 14)

scala> m("zhangsan")
res23: Int = 13

scala> m.get("zhangsan")
res24: Option[Int] = Some(13)

scala> m.get("zhangsan1")
res25: Option[Int] = None

scala> m.getOrElse("zhangsan","默认值")
res26: Any = 13

scala> m.getOrElse("zhangsan1","默认值")
res27: Any = 默认值

2.值不可变

scala> import scala.collection.mutable.Map
import scala.collection.mutable.Map

scala> val m1 = scala.collection.mutable.Map("zhangsan" -> 13,"lisi" -> 20)
m1: scala.collection.mutable.Map[String,Int] = Map(lisi -> 20, zhangsan -> 13)

scala> m1("zhangsan")
res30: Int = 13

scala> m1.get("zhangsan")
res31: Option[Int] = Some(13)

scala> m1("zhangsan")=16

scala> m1
res33: scala.collection.mutable.Map[String,Int] = Map(lisi -> 20, zhangsan -> 16)

map的遍历

	val m = scala.collection.mutable.Map("zhangsan" -> 13,"lisi" -> 14)
    for (elem <- m) {
      println(elem)
    }
    for ((k,v) <- m) {
      println(k + "->" + v)
    }
    for (k <- m.keySet){
      println(k + "===>" + m.getOrElse(k,-99))
    }
    for (v <- m.values){
      println(v)
    }

11.case class 样例类【用的偏多】
class 与 case class 区别:
1.case class 不用new
2.case class 默认就实现了 序列化 【非常重要】
3.case class 重写了 toString equals hashcode

def main(args: Array[String]): Unit = {
    val dog: Dog = Dog("旺财")
    dog.f01()
  }
  case class Dog(name:String){
    def f01()={
      println(name)
    }
  }
scala> class Person(name:String,age:Int)
defined class Person

scala> val p1 = new Person("zhangsan",10)
p1: Person = Person@4fd7b798

scala> val p2 = new Person("zhangsan",10)
p2: Person = Person@414e4d33

scala> p1 == p2
res34: Boolean = false

scala> case class Dog(name:String)
defined class Dog

scala> val d1 = Dog("xiaotian")
d1: Dog = Dog(xiaotian)

scala> val d2 = Dog("xiaotian")
d2: Dog = Dog(xiaotian)

scala> d1 == d2
res35: Boolean = true

scala> println(p2)
$line56.$read$$iw$$iw$Person@414e4d33

scala> println(d2)
Dog(xiaotian)

12.模式匹配
1.匹配内容
xxx match {
case xx
case xxx
}
2.匹配类型
3.匹配集合
4.匹配case class

def main(args: Array[String]): Unit = {
    val teachers: Array[String] = Array("马老师", "张老师", "卢老师", "刘浩存")
    val name: String = teachers(Random.nextInt(teachers.length))
    name match {
        case "马老师" => println("这是马老师")
        case "卢老师" => println("这是班主任")
        case "张老师" => println("领导")
        case _ => println("这是谁呀")
    }
    mathType(1)
    mathType("tom")
    mathType(Map("tom" -> 13))
    mathType(true)
  }
  def mathType(obj:Any): Unit ={
    obj match {
       case x:Int => println("Int")
       case s:String => println("String")
       case m:Map[_,_] => println("Map")
       case _ => println("other type")
    }
  }
def main(args: Array[String]): Unit = {
    mathList(List("tom","jack"))
    mathList(List("tom"))
    mathList(List(""))

  }
  def mathList(list:List[String]): Unit ={
    list match {
      case x::y::Nil => println(s"集合中只有两个元素${x},${y}")
      case "tom"::Nil => println("集合中只有一个元素tom")
      case _ => println("other")
    }
  }
 def main(args: Array[String]): Unit = {
    val caseInfo =Array(
      CheckTimeoutTask,HeartBeat(3000),SubmitTask("100","task100")
      )
    val caseData: Object = caseInfo(Random.nextInt(caseInfo.length))
    caseData match {
      case CheckTimeoutTask => println("CheckTimeoutTask")
      case HeartBeat(time) => println("HeartBeat")
      case SubmitTask(id,name) => println("SubmitTask")
    }
  }
  case class SubmitTask(id:String,name:String)
  case class HeartBeat(time:Long)
  case class CheckTimeoutTask()

基本语法

1.偏函数 PartialFunction
用法:
定一个方法,返回值是偏函数 {
方法体: 一堆case语句
}
A:表示输入参数类型
B:表示输出参数类型

def main(args: Array[String]): Unit = {
    val course: Array[String] = Array("spark", "flick", "hive")
    val item: String = course(Random.nextInt(course.length))
    println(item)
    println(teacher(item))
  }
  def teacher:PartialFunction[String,String]={
    case "spark" => "批流一体框架"
    case "hive" => "离线计算框架"
    case _ => "其他计算框架"
  }

2.柯力化 currying =》 这个定义是必然发生 的结果
def sum(x:Int,y:Int)
def sum(x:Int)(y:Int) 柯力化 源码多 用隐式转换的目的 定义一个参数列表现在拆成两个

def main(args: Array[String]): Unit = {
    println(sum(1, 2))
    println(sum01(3)(4))
  }
  def sum(x:Int,y:Int)={
    x+y
  }
  def sum01(x:Int)(y:Int)={
    x+y
  }

3.io => 读写文件 url
Source
val content: BufferedSource = Source.fromFile(“data/wc.data”)
val lines = content.getLines()

def main(args: Array[String]): Unit = {
    val content: BufferedSource = Source.fromFile("data/wc.data")
    val lines: Iterator[String] = content.getLines()
    lines.foreach(println(_))
  }

需求: 读取文件内容,统计每个单词出现的次数 结果数据输出到控制台 【按照单词次数进行降序输出】

 def main(args: Array[String]): Unit = {
    val source: BufferedSource = Source.fromFile("data/wc.data")
    val content: Iterator[String] = source.getLines()
    val words: Iterator[String] = content.flatMap(x => x.split(","))
    val words2one: Iterator[(String, Int)] = words.map(x => (x, 1))
    val groupbyData: Map[String, Array[(String, Int)]] = words2one.toArray.groupBy(x => x._1)
    val wc: Map[String, Int] = groupbyData.mapValues(v => v.map(v => v._2).sum)
    val result: List[(String, Int)] = wc.toList.sortBy(x => -x._2)
    for (kv <- result) {
      println(kv)
    }
  }

4.隐式转换
目的:增强
eg: A类 =》 B类
B对A已有的东西进行增强 【感知不到】
隐式转换:
1.隐式参数 【作用到 方法参数上】
2.隐士类型转换 【作用到def上】 常用的
3.隐士类 【作用到class上】 高危的

 def main(args: Array[String]): Unit = {
    implicit def man2superman(man:Man):SuperMan={
      new SuperMan(man.name)
    }
    val zzx: SuperMan = new SuperMan("zzx")
    zzx.fly()
    val tom: Man = new Man("tom")
    tom.fly()
  }
  class Man(val name:String)
  class SuperMan(name:String){
    def fly()={
      println(s"${name} can fly...")
    }
  }
def main(args: Array[String]): Unit = {
    println(4.add(5))
  }
  implicit class Cal(x:Int){
    def add(a:Int)=a+x
  }
def main(args: Array[String]): Unit = {
    implicit def File2RichFile(file:File):RichFile={
      new RichFile(file)
    }

    val file: File = new File("data/wc.data")
    println(file.read())
  }
  class RichFile(file:File){
    def read()={
      //Source.fromFile(file.getPath).getLines()
      Source.fromFile(file.getPath).mkString
    }
  }

5.泛型:类型的约束

def main(args: Array[String]): Unit = {
    val chat: WeChat = new WeChat("dl2262")
  }
  abstract class MSG[S](content:S)
  class WeChat(content:String) extends MSG(content)
  class QQChat[Int](content:Int) extends MSG(content)
  class ZFBChat(content:BigInt) extends MSG[BigInt](content)
 def main(args: Array[String]): Unit = {
    val tom: GG[FaceValueEnum, Int, Double] = new GG[FaceValueEnum, Int, Double](FaceValueEnum.A, 181, 8)
    val jack: GG[FaceValueEnum, Int, Double] = new GG[FaceValueEnum, Int, Double](FaceValueEnum.D, 182, 11)
    println(
      s"""
        |${tom}
        |${jack}
        |""".stripMargin)
  }
  class GG[A,B,C](val faceValue:A,val height:B,val chuanzhuo:C){
    override def toString: String = faceValue + "\t" + height + "\t" + chuanzhuo
  }
  object FaceValueEnum extends Enumeration{
    type FaceValueEnum = Value
    val A,B,C,D = Value
  }

6.上界:

T是 Test的子类
<? extends Test>
下界:

T 可以是Test的父类型
<? super Test>
7.逆变 vs 协变: [了解]
- +
8.scala排序:
java:
1.comparator
2.Comparable
scala:
1.Ordering => Comparator => compare
2.Ordered => Comparable => compareTo

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值