Step into Scala - 06 - 流程控制

目录

摘要

if 与表达式与 else,for,until,for 与字符串,for 与对象列表,break 与 continue,生成器,守卫,循环变量,yield,map,FlatMap,filter,stream,iterator

流程控制

条件表达式

if/else 结构与 Java 类型,不过由于 Scala 面向表达式,所以可以直接将表达式赋给一个变量。

val s = if (x > 0) 1 else -1

这种方式可以给常量赋值,有点类似 Java 中得三元操作符,此时 s 的类型为 Int

如果下面这种混合型的,s 的类型就为 Any

val s = if (x > 0) "a" else 65

因为 Scala 中表达式都必须有值,所以如果没有 else 的话,需要引入 Unit 类,写作 ()

if (x > 0) 1 else ()

循环

while 和 do-while

Scala 中的 whiledo-while 类似 Java

for
基本使用
for (i <- 1 to n)

此表达式表示让变量 i 遍历 <- 右边的表达式的所有值 ( “1” 到 “n” )
变量 i 不需要事先定义,循环变量的作用域会一直持续直到循环结束。

for (i <- 1 until n)
until

until 表示不包含上区间

for (i <- 1 until 5)
  print(i) //1234
println()
用于字符串上
for (ch <- "Hello")
  sum += ch
用于对象列表

for 也可以用在对象列表上

class Person(val name: String, val age: Int) {
}

val persons = List(new Person(name = "Jane", age = 18), new Person(name = "Peter", age = 20),
  new Person(name = "Anna", age = 15), new Person(name = "Andy", age = 22))

val ages = for (p <- persons if p.age > 20) yield p.age
//以上代码实际会被翻译成如下代码
val newAges = persons filter (p => p.age > 20) map (p => p.age)

println(ages) //List(22)
println(newAges) //List(22)
break 和 continue

Scala 没有提供 breakcontinue 来退出循环,需要自己定义 boolean 变量来控制或者从函数中 return。

高级 for 循环
生成器

生成器的格式是 变量 <- 表达式

for 循环中可以同时使用多个生成器,每个生成器之间用分号隔开,或者换行分隔。

for (i <- 1 to 3; j <- 3 to 5) {
  print(i, j)   //(1,3)(1,4)(1,5)(2,3)(2,4)(2,5)(3,3)(3,4)(3,5)
}
守卫

每个生成器都可以带一个守卫,守卫是以 if 开头的布尔表达式

for (i <- 1 to 3; j <- 3 to 5 if i == j) {
  print(i, j)   //(3,3)
}
循环变量

for 循环中也可以自由定义任何变量,不用以 val 和 var开头

for(i <- 1 to 3; from = 4 - i; j <- from to 3)
yield

如果 for 循环的循环体以 yield 开头,则该循环会生成一个集合,每次迭代生成集合中的一个值。这种 for 循环称为 “for 推导式”。

var result = for (i <- 1 to 10) yield {
  i % 3
}
println(result) //Vector(1, 2, 0, 1, 2, 0, 1, 2, 0, 1)

“for 推导式” 生成的集合与它的第一个生成器是类型兼容的。

隐式 for 循环
概念

由于 for 循环是非常常用的方法,所以 Scala 提供了很多简便方法

Map

Map 用于对列表中的每一个元素进行遍历

val persons = List(new Person(name = "Jane", age = 18), new Person(name = "Peter", age = 20),
  new Person(name = "Anna", age = 15), new Person(name = "Andy", age = 22))

persons.map(p => p.age) //List(18, 20, 15, 22)
FlatMap

FlatMap 用于对列表中的每一个元素应用函数并以列表形式返回结果。

val persons = List(new Person(name = "Jane", age = 18), new Person(name = "Peter", age = 20),
  new Person(name = "Anna", age = 15), new Person(name = "Andy", age = 22))

persons.flatMap(p => List(p.age)).foreach(p => println("flatMap", p))   //(flatMap,18)(flatMap,20)(flatMap,15)(flatMap,22)
Filter

Filter 用于对按照布尔值对列表中元素进行过滤。

val persons = List(new Person(name = "Jane", age = 18), new Person(name = "Peter", age = 20),
  new Person(name = "Anna", age = 15), new Person(name = "Andy", age = 22))

persons.filter(p => {
  if (p.age > 20) true else false
}).foreach(p => println("filter", p.age))   //(filter,22)

Stream

概念
  • 由于实际编程中像 [start .. end-1] 这种形式的遍历非常常见,所以 Scala 提供了 Stream 来进行简便操作。
  • Stream 对象是不可变对象,由单个元素的头部及其余部分组成的尾部构成
使用方法
指定范围
var r: Stream[Int] = Stream.range(1, 5)
println(r, r.getClass, r.head, r.tail) //(Stream(1, 2, ?),class scala.collection.immutable.Stream$Cons,1,Stream(2, ?))
r.foreach(i => println(i)) //1,2,3,4

以上方法内部实现类似下面的代码

def range(start: Int, end: Int): Stream[Int] = {
  if (start >= end) Stream.Empty
  else Stream.cons(start, range(start + 1, end))
}
r = range(1, 5)
println(r, r.getClass, r.head, r.tail) //(Stream(1, 2, ?),class scala.collection.immutable.Stream$Cons,1,Stream(2, ?))
r.foreach(i => println(i)) //1,2,3,4
连接元素

Stream.cons(ele, stream) 可以用于追加新元素到头部并返回新生产的 Stream 对象,该方法实际就类似 Lista::b

var nr = Stream.cons(30, Stream.range(1, 5))
println(nr, nr.getClass, nr.head, nr.tail) //(Stream(30, 1, ?),class scala.collection.immutable.Stream$Cons,30,Stream(1, ?))
nr.foreach(i => println(i)) //30,1,2,3,4

Iterator

概念

IteratorStream 一样,也是用于对数据进行遍历

创建 Iterator
val it: Iterator[Int] = Iterator.range(1, 5)
while (it.hasNext) {
  val v = it.next()
  println("it", v) //1,2,3,4
}
Map

map 用于遍历每个元素并对每个元素应用方法,返回函数的执行结果

val it2 = Iterator.range(1, 5).map(i => i + 5)
while (it2.hasNext) {
  val v = it2.next()
  println("it2", v) //6,7,8,9
}
FlatMap

FlatMap 类似 map,但返回的是 Iterator

val it3 = Iterator.range(1, 5).flatMap(i => Iterator.range(i, i + 2))
while (it3.hasNext) {
  val v = it3.next()
  println("it3", v) //1,2|2,3|3,4|4,5
}
for each
Iterator.range(1, 5).foreach(i => println("it4", i)) //1,2,3,4
Filter

Filter 根据返回的布尔值过滤对应值。

val it5 = Iterator.range(1, 5).filter(i => i % 2 == 0)
while (it5.hasNext) {
  val v = it5.next()
  println("it5", v) //2,4
}
Zip

Zip 用于连接两个 Iterator 的值,返回匹配后的新的 Iterator

var it6 = Iterator.range(1, 5).zip(Iterator.range(10, 20))
while (it6.hasNext) {
  val v = it6.next()
  println("it6", v) //(1,10),(2,11),(3,12),(4,13)
}
it6 = Iterator.range(1, 5).zip(Iterator.range(10, 12))
while (it6.hasNext) {
  val v = it6.next()
  println("it6", v) //(1,10),(2,11)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值