scala之学习笔记

一、scala简介

Scala是一门运行在JVM上的多范式的编程语言,一种类似java的编程语言,设计初衷是实现可伸缩的语言、并集成面向对象编程和函数式编程的各种特性。被应用于spark、flink开发。

二、基本语法

1、变量定义

val name ="zhangsan"  //val定义的变量不可被重新赋值
var name ="lisi"
//惰性赋值
lazy val name ="zhangsan" //用到时才会加载到内存

2、变量表达式

//数据类型,与java类似,注:scala中所有类型都是大写字母开头
val name ="zhangsan"
val info =s"${name},你好!!"  //使用三个""" """内的内容都会被解释为字符串

3、条件表达式

在scala中条件表达式也是有返回值的,没有三元表达式

1>、if表达式

val sex="zhangsan"
val result=if(sex=="zhangsan") 1 else 0

2>、for、while表达式

val nums = 1.to(10) //定义1到10的数据集
for(i<-nums)print(i) //循环打印1到10的数字

//守卫
for表达式中可以添加if判断,这个if判断就称为守卫
for(i<- 1 to 10 if i%3==0)println(i)  //打印1到10内能被3整除的数

//for推导式
/**在for循环体中,可以使用yield表达式构建出一个集合,我们把使用yield的for表达式称之为推导式*/
val v = for(i <- 1 to 10) yield i * 10  //用1到10的集合构建,(10,20,30....)的新集合

//while循环和java一样

4、break和continue

/**注:在scala中,类似Java和C++的break/continue关键字被移除了,如果一定要使用break/continue,就需要使用scala.util.control包的Break类的breable和break方法。*/
//break实现(breakable包for的整个表达式)
import scala.util.control.Breaks._  //导入Breaks包
breakable{ for(i <- 1 to 100) { if(i >= 50) break() else println(i) } }  //使用for表达式打印1-100的数字,如果数字到达50,退出for表达式

//continue实现(breakable包for表达式的循环体)
import scala.util.control.Breaks._
for(i <- 1 to 100 ) { breakable{ if(i % 10 == 0) break() else println(i) } } //打印1-100的数字,使用for表达式来遍历,如果数字能整除10,不打印

5、方法

def add(a:Int, b:Int) = a + b  //实现两个整数相加和,注:参数列表的参数类型不能省略,返回值可以不写return,默认就是{}块表达式的值,返回值类型可以省略,除递归方法外
//正确写法
def m2(x:Int):Int={  if(x<=1) 1  else m2(x-1)*x }
//错误写法
def m2(x:Int)={  if(x<=1) 1  else m2(x-1)*x }

//方法参数
def add(x:Int = 0, y:Int = 0) = x + y      
add()   //默认参数     
add(x=1)  //带名参数
def add(num:Int) = num.sum                 
add(1,2,3,4,5)    //变长参数,计算1,2,3,4,5的和

//方法调用方式
Math.abs(-1) //后缀调用法,返回-1的绝对值
Math abs -1     //中缀调用法,返回-1的绝对值
Math.abs{-1} //花括号调用法,返回-1的绝对值
def m3()=println("hello")      
m3  //无括号调用法

6、函数

val add = (x:Int, y:Int) => x + y
//方法函数的区别
    /**1、方法是隶属于类或者对象的,在运行时会加载到JVM的方法区中
    2、可以将函数对象赋值给一个变量,在运行时,它是加载到JVM的堆内存中
    3、函数是一个对象,继承自FunctionN,函数对象有apply,curried,toString,tupled这些方法。方法则没有*/

//方法转换为函数
def add(x:Int,y:Int)=x+y
val a = add _            //使用_即可将方法转换为函数

7、数组

val a = Array("java", "scala", "python")   //定长数组
    
import scala.collection.mutable.ArrayBuffer     
val a = ArrayBuffer("hadoop", "storm", "spark") //变长数组,需引入ArrayBuffer的类,使用+=添加元素,使用-=删除元素,使用++=追加一个数组到变长数组

//遍历数组
val a = Array(1,2,3,4,5) 
for(i<-a) println(i)    //for表达式直接遍历
for(i <- 0 to a.length - 1) println(a(i))   //使用for表达式基于索引下标遍历
/**注:
    0 until n——生成一系列的数字,包含0,不包含n
    0 to n ——包含0,也包含n*/

//数组的常用算法
val a = Array(1,2,3,4)
a.sum      //求和
a.max    //最大值
a.min    //最小值
a.sorted    //升序
a.sorted.reverse  //降序

8、元组

//元组可以用来包含一组不同类型的值。例如:id,姓名,年龄,地址。元组的元素是不可变的
val a = (1, "zhangsan", 20, "beijing")
val a = ("zhangsan", 20) //使用括号定义元组
val a = "zhangsan" -> 20 //使用箭头定义元组

//访问元组
a._1  //元组的第一个元素
a._2  //元组的第二个元素

9、列表(可以保存重复的值,有先后顺序)

//不可变列表,元素,长度均不可变
val a = List(1,2,3,4)   
val a = Nil  //不可变得空列表
val a = -2 :: -1 :: Nil   //使用::方法创建列表

//可变列表,元素长度均可变
import scala.collection.mutable.ListBuffer   //导入依赖的包
val a = ListBuffer[Int]()  //定义空列表
val a = ListBuffer(1,2,3,4) //获取元素(使用括号访问(索引值)),添加元素(+=),追加一个列表(++=),更改元素(使用括号获取元素,然后进行赋值),删除元素(-=),转换为List(toList),转换为Array(toArray)

//列表常用操作
val a = List(1,2,3,4)
val b = List(4,5,6)
a.isEmpty   //判断列表是否为空
a ++ b        //拼接两个列表
a.head        //获取列表的首个元素
a.tail         //获取列表的剩余部分
a.reverse    //反转列表
a.take(3)   //列表前缀(前三个元素)
a.drop(3)    //列表后缀(除前三个元素)
val a = List(List(1,2), List(3), List(4,5))
a.flatten     //扁平化(将列表中的列表中的所有元素放到一个新列表中List(1,2,3,4,5))

val a = List("zhangsan", "lisi", "wangwu")
val b = List(19, 20, 21)
val c = a.zip(b)    //拉链List((zhangsan,19), (lisi,20), (wangwu,21)) 
c.unzip        //拉开(List(zhangsan, lisi, wangwu),List(19, 20, 21))

val a = List(1,2,3,4)
println(a.toString)   //转换字符串"""List(1, 2, 3, 4)"""
a.mkString(":")            //生成字符串1:2:3:4

val a1 = List(1,2,3,4)
val a2 = List(3,4,5,6)
a1.union(a2)          //并集
a1.union(a2).distinct  //并集调用distinct去重
a1.intersect(a2)      //交集
a1.diff(a2)            //差集

10、集合(元素不重复,无序)

val a = Set(1,1,3,2,4,8)  //不可变集合

//基本操作
val a = Set(1,1,3,2,4,8)    
a.size            //获取集合大小
for(i <- a) println(i)        //遍历集合
a - 1         //删除一个元素
a ++ Set(6,7,8)        //拼接两个集合
a ++ List(6,7,8,9)    //拼接集合和列表
//注:可变列表需带入此包import scala.collection.mutable.Set

11、映射

val map = Map("zhangsan"->30, "lisi"->40)

//基本操作
val map = Map("zhangsan"->30, "lisi"->40) 
map("zhangsan")        //获取指定key的值
map.keys               //获取所有的key
map.values             //获取所有的值
for((x,y) <- map) println(s"$x $y") //遍历map集合
map.getOrElse("wangwu", -1)        //判断指定key是否存在,不存在返回-1
map + "wangwu"->35                //增加一个键值对
map - "lisi"                     //删除指定key及值

12、迭代器iterator

val a = List(1,2,3,4,5)
val ite = a.iterator
while(ite.hasNext) { println(ite.next) }   //while迭代遍历并打印列表
for(i <- a) println(i)                    //for遍历打印列表

三、函数式编程

后面Spark/Flink的大量业务代码都会用到函数式编程

val a = List(1,2,3,4)
//遍历
a.foreach(x=>println(x))    //foreach遍历
a.foreach(println(_))        //foreach下划线简写遍历
//映射
a.map(x=>x+1)                //映射List(2,3,4,5)
a.map(_ + 1)                //下划线式映射List(2,3,4,5)

val a = List("hadoop hive spark flink flume", "kudu hbase sqoop storm") 
//扁平化映射
a.map(x=>x.split(" "))        //按照空格切割映射为新的列表List(Array(hadoop, hive, spark, flink, flume), Array(kudu, hbase, sqoop, storm))
a.map(x=>x.split(" ")).flatten    //映射并扁平化List(hadoop, hive, spark, flink, flume, kudu, hbase, sqoop, storm)
a.flatMap(_.split(" "))          //扁平化映射,相当于上一条List(hadoop, hive, spark, flink, flume, kudu, hbase, sqoop, storm)

val a = List(1,2,3,4)
//过滤
a.filter(_ % 2 == 0)    //过滤能被2整除的,List(2,4)
//排序
List(3,1,2,9,7).sorted  //默认排序
val a = List("01 hadoop", "02 flume", "03 hive", "04 spark")
a.sortBy(_.split(" ")(1))        //指定字段排序{将列表内元素按照空格切分,并指定切分后的第二个元素排序,即按照单词字母排序List(02 flume, 01 hadoop, 03 hive, 04 spark)}
val a = List(2,3,1,6,4,5)
a.sortWith((x,y) => if(x<y)true else false)  //sortWith自定义排序
a.sortWith(_ < _).reverse            //sortWith自定义排序简写

val a = List("张三"->"男", "李四"->"女", "王五"->"男")
//分组
a.groupBy(_._2)            //按照性别分组

val a = List(1,2,3,4,5,6,7,8,9,10)
//聚合
a.reduce((x,y) => x + y)     //聚合
a.reduceLeft(_ + _)         //从左往右聚合
a.reduceRight(_ + _)        //从右往左聚合
a.fold(0)(_ + _)            //同reduce一样,但须指定初始值参数(foldRight表示从右往左计算,foldRight表示从右往左计算)

猜你喜欢

转载自www.cnblogs.com/zhaihongchang/p/12212649.html