55 Scala条件表达式、循环、方法、集合、函数式编程

条件表达式

有返回值的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可称之为映射

不可变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)(_+_)
上一篇:方法


下一篇:map函数映射 洛谷p1102