条件表达式
有返回值的if
// scala中,条件表达式也是有返回值的
// scala中,没有三元表达式,可以使用if表达式替代三元表达式
val sex = "male"
val result = if(sex == "male" 1 else 0)
块表达式
// 块表达式也是有返回值的
// 返回的是最后一个表达式的值
val a = {
println("hello world")
1 + 1
}
循环
简单循环
for(i <- 1 to 10) println(i)
嵌套循环
for(i <- 1 to 3; j <- 1 to 5) {print("*"); if(j == 5) println("")}
守卫
for(i <- 1 to 10 if 1%3 == 0) println(i)
for推导式
// for表达式中以yield开始,该for表达式会构建出一个集合
val v = for(i <- 1 to 10) yield i*10
方法
定义方法
def add(x:Int, y:Int):Int = x * y
add(1,2)
方法参数
// 默认参数
//x, y带有默认值
def add(x:Int = 10, y:Int = 0) = x + y
add()
// 带名参数
def add(x:Int = 0, y:Int = 0) = x + y
add(x=1)
// 变长参数
def add(num:Int*) = num.sum
add(1,2,3,4,5)
方法返回值类型判断
// scala定义方法可以省略返回值,由scala自动推断返回值类型
// 定义递归返回,不能省略返回值
方法调用方式
// 后缀调用法
Math.abs(-1)
// 中缀调用法
1 to 101 + 1 //操作符是一个方法名字是符号的方法
// 花括号调用法
Math.abs{-1} //方法只有一个参数,才能使用花括号调用方法
// 无括号调用法
//如方法没有参数,可以省略方法名后面的括号
def m3() = println("hello")
m3
函数
方法和函数的区别
- 方法属于类或者对象,运行时,加载到JVM的方法区中
- 方法无法赋值给对象
- 可以将函数对象赋值给一个变量,运行时,加载到JVM的堆内存中
- 函数是一个对象,继承自FunctionN
- 函数对象有apply,curried,toString,tupled这些方法,方法则没有
方法转换为函数
// 使用 _ 即可将方法转换为函数def add(x:Int, y:Int) = x + yval a = add _
数组
定长数组
// scala中,数组的泛型使用[]来指定
// 使用()来获取元素
val a = new Array[Int](100)
a(0) = 100
val a = Array("java","scala","python")
a.length
变长数组
// 创建变长数组,需要提前导入
// import scala.collection.mutable.ArrayBufferval a = ArrayBuffer[Int]()
val a = ArrayBuffer("hadoop","storm","spark")
添加/修改/删除元素
// 使用 += 添加元素
// 使用 -= 删除元素
// 使用 ++= 追加一个数组到变长数组
val a = ArrayBuffer("hadoop", "spark", "flink")
a += "flume"
a -= "hadoop"
a ++= Array("hive", "sqoop")
遍历数组
// 使用for表达式直接遍历
val a = Array(1,2,3,4,5)
for(i <- a) println(i)
// 使用for表达式基于索引下标遍历
val a = Array(1,2,3,4,5)
for(i <- 0 to a.length-1) println(i)
for(i <- 0 until a.length) println(i)
数组常用算法
// 求和 sumval
a = Array(1,2,3,4)
a.sum
// 求最大/最小值
max/minval a = Array(4,2,1,4,10)
a.max
// 排序 sorted
a.sorted
// 降序排序
a.sorted.reverse
元组
- 元组可以用来包含一组不同类型的值
- 元组的元素是不可变的
定义元组
// 用括号来定义元组
val a = (1,"张三",20,"北京市")
// 使用箭头(元组只有两个元素)
val a = 1->2
访问元组
// 使用_1, _2 ...来访问元组中的元素
// _1表示访问第一元素,依次类推
// 不能修改元组中的值
val a = (1,"zhangshan","20","beijing")
a._1
列表
不可变列表
// 使用List()方式创建
val a = List(1,2,3,4)
// 使用 Nil 创建一个不可变的空列表
val a = Nil
// 使用 :: 创建一个不可变列表
val a = -2 :: -1 :: Nil
可变列表
// 要先导入 import scala.collection.mutable.ListBuffer
// 可变集合都在mutable包中
// 不可变集合都在immutable包中(默认导入)
val a = ListBuffer[Int]()
val a = ListBuffer(1,2,3,4)
列表操作
val a = ListBuffer(1,2,3)
// 获取元素
a(0)
// 添加/删除元素 +=/-=
a += 4
// 追加一个列表 ++=
a ++= List(5,6,7)
// 转换为List toList
a.toList
// 转换为Array toArray
a.toArray
列表常用操作
val a = List(1,2,3,4)
// 判断列表是否为空 isEmpty
a.isEmpty
// 拼接两个列表 ++
val b = List(4,5,6)
a ++ b
// 获取列表的首个元素(head)和剩余部分(tail)
a.heada.tail
// 反转列表 reverse
a.reverse
// 获取前缀(take)获取后缀(drop)
a.take(3)
a.drop(3) //获取除了前3个以外的元素
// 扁平化 flatten
//扁平化表示将列表中的列表中的所有元素放到一个列表中
val a = List(List(1,2), List(3), List(4,5))
a.flatten
// 拉链(zip)拉开(unzip)
val a = List("zhangshan","lisi","wangwu")
val b = List(19, 20, 21)
val c = a.zip(b)
c.unzip
// 转化为字符串 toString
a.toString
// 生成字符串 mkString
a.mkString(",")
// 并集 union
//对两个列表取并集,不去重
val a1 = List(1,2,3,4)
val a2 = List(1,2,3,4)
a1.union(a2)
//可以调用distinct去重
a1.union(a2).distinct
// 交集 intersect
a1.intersect(a2)
// 差集 diff
a1.diff(a2)
Set
不可变集
// 创建集
val a = Set(1,1,2,3,4)
// 获取集的大小 size
a.size
// 遍历集
for(i <- a) println(i)
// 删除元素
a - 1
// 拼接两个集,生成一个Set ++
a ++ Set(6,7,8)
// 拼接集和列表,生成一个Set ++
a ++ List(6,7,8,9)
可变集
//手动导入 import scala.collection.mutable.Set
Map
不可变Map
val map = Map("zhangshan"->30, "lisi"->40)
val map = Map(("zhangshan", 30), ("lisi", 30))
可变Map
//手动导入 import scala.collection.mutable.Map
Map基本操作
val map = Map("zhangshan"->30, "lisi"->40)
// 获取值
map("zhangshan")
// 获取所有key map.keys
map.keys
// 获取所有value map.values
map.values
// 遍历Map集合
for((x, y) <- map) println(s"$x $y")
// getOrElse
// 获取wangwu的年龄,如果wangwu不存在,则返回-1
map.getOrElse("wangwu", -1)
// 增加key,value对 +
map + "wangwu"->35
// 删除key -
map - "lisi"
函数式编程
遍历 foreach
val a = List(1,2,3,4)
a.foreach((x:Int) => println(x))
使用类型推断简化函数定义
// scala可以自动推断出集合中每个元素参数的类型
// 创建函数时,可以省略其参数列表的类型
a.foreach(x => println(x))
使用下划线来简化函数定义
// 当函数的参数,只在函数体中出现一次
// 而且函数体没有嵌套调用时
// 可以使用下划线来简化函数定义
a.foreach(println(_))
映射 map
// map方法接收一个函数,将这个函数应用到每一个元素,返回一个新的列表
a.map(x => x+1)
val a = List(1,2,3,4)
a.map(_ + 1)
扁平化 flatMap
// 使用map将文本行拆分为数组
// 再对数组进行扁平化
val a = List("hadoop hive spark flink flume", "kudu hbase sqoop storm")
a.map(x => x.split(" ")).flatten
// 使用flatMap简化操作
a.flatMap(_.split(" "))
过滤 filter
List(1,2,3,4,5,6,7).filter(_ % 2 == 0)
排序
// 默认排序 sorted
List(3,2,1,9,7).sorted
// 指定字段排序 sortBy
val a = List("01 hadoop", "02 flume", "03 hive", "04 spark")
a.sortBy(_.split(" ")(1))
// 自定义排序 sortWith
a.sortWith((x,y) => if(x<y) true else false)
a.sortWith(_<_).reverse
分组 goupBy
val a = List("张三"->"男", "李四"->"女", "王五"->"男")
val b = a.gropBy(_._2)
b.map(x => x._1 -> x._2.size)
聚合 reduce
val a = List(1,2,3,4,5,6,7,8,9,10)
a.reduce(_+_)
聚合 fold
// 和reduce很像,但是多指定了一个初始值参数
val a = List(1,2,3,4,5,6,7,8,9,10)
a.fold(0)(_+_)