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