3.2 循环结构

Scala同样提供了对程序流程控制的语法。Scala中的程序流程控制结构虽然与Java类似,但也有自己的一些独特的方法。

循环结构

经常地,我们需要遍历集合中的元素,或者对集合中的每个元素进行操作,或者从现有集合创建一个新集合,这就需要用到循环结构。Scala拥有与Java和C++相同的while和do-while循环。

下面是使用while的循环语句:

var sum = 0
var i = 1
while(i < 11) {
  sum += i
  i += 1
}
sum
i

输出结果如下:

sum: Int = 0 
i: Int = 1

res26: Int = 55
res27: Int = 11

请看下面的示例代码:

// while语句 
var i = 1
while (i <= 5) {
  println("hello")
  i = i + 1
}

//输出1到10的偶数
//方法1
var j = 1
while (j <= 10) {
//如果j是偶数
if (j % 2 == 0) {
  println(j)
}
j = j + 1
}

//方法2
var k = 2
while (k <= 10) {
println(k)
k = k + 2
}

输出结果如下:

i: Int = 1 
hello
hello
hello
hello
hello

j: Int = 1
2
4
6
8
10

k: Int = 2
2
4
6
8
10

Scala 也有do-while循环,它和while循环类似,只是检查条件是否满足在循环体执行之后检查。例如:

var sum = 0
var i = 1
do {
  sum += i
  i += 1
} while(i <= 10)

println("1+...+10=" + sum)

Scala也提供了for循环和foreach方法。下面的代码使用for-each循环来遍历数组:

val a = Array("apple", "banana", "orange")
for (e <- a) println(e)

for (e <- a) {
  val s = e.toUpperCase
  println(s)
}

可以在for表达式内部定义变量,然后,可以在for表达式的body中重用这些变量,这称为”变量绑定”。如下代码所示:

val books = Array("Scala从入门到精通", "Groovy从入门到精通", 
              "Java从入门到精通", "24小时精通Scala", "24小时精通Java")

for {book <- books
  bookVa1 = book.toUpperCase()
  bookVa2 = book.toLowerCase()
} println(bookVa1 + "," + bookVa2)

注意to和until的区别。until不包含上边界值,而to包含上边界值。请看下面的代码:

object Hello {
def main(args:Array[String]){  
  for(i <- 1 until 10){
    print(i + " ")      
  }
   
  println()
   
  for(i <- 1 to 10){
    print(i + " ")
  }
}
}

输出结果如下所示:

1 2 3 4 5 6 7 8 9 
1 2 3 4 5 6 7 8 9 10

【示例】遍历数组。

// 声明数组
var myList = Array(1.9, 2.9, 3.4, 3.5)

// 输出所有数组元素
for ( x <- myList ) {
println( x )
}

// 计算数组所有元素的总和
var total = 0.0;
for ( i <- 0 to (myList.length - 1)) {
total += myList(i);
}
println("总和为 " + total);

// 查找数组中的最大元素
var max = myList(0);
for ( i <- 1 to (myList.length - 1) ) {
if (myList(i) > max) max = myList(i);
}
println("最大值为 " + max);

注:实际上可以用高阶函数,更加简洁地遍历数组(集合)。例如:

// 遍历 
var myList = Array(1.9, 2.9, 3.4, 3.5)
myList.map(println)
myList.foreach(println)

【示例】登录用户名密码的游戏:三次机会,从控制台输入输入用户名密码,如果成功登录,返回登录成功,失败,则反馈错误信息!如下:

import scala.io.StdIn

object Example02 {
def main(args: Array[String]): Unit = {
val dbUser = "mm"
val dbPassword = "1234"
var count = 3

while(count > 0) {
val username = StdIn.readLine("请输入账号:")
val userpwd = StdIn.readLine("请输入密码:")
if(username == dbUser && userpwd == dbPassword) {
println(s"登陆成功,欢迎$username!")
count = 0
} else {
count -= 1
println("用户名或密码错误!您还有<$count>次机会!")
}
}
}
}

在循环中使用if条件过滤值

在Scala中,还可以使用if子句来在遍历条目时添加过滤支持。例如,在下面的示例中,将水果名称长度超过2的过滤掉。

object demo {
def main(args: Array[String]): Unit = {
println("在for循环中使用if条件过滤值")
val fruits = List("苹果","香蕉","桃子","猕猴桃","凤梨")
for(fruit <- fruits if fruit.length<3){
println(fruit)
}
}
}

输出结果如下所示:

在for循环中使用if条件过滤值
苹果
香蕉
桃子
凤梨

在for循环中使用if条件过滤值,并使用yield关键字返回结果。

object demo04 {
def main(args: Array[String]): Unit = {
println("\n在for循环中使用if条件过滤值,并使用yield关键字返回结果")
val fruits = List("苹果","香蕉","桃子","猕猴桃","凤梨","杏","无籽西瓜","水晶葡萄")
val fruitTwo = for {
fruit <- fruits
if fruit.length == 3 || fruit.length == 4
} yield fruit
println(s"过滤后的水果有 = $fruitTwo")
}
}

输出结果如下所示:

在for循环中使用if条件过滤值,并使用yield关键字返回结果
过滤后的水果有 = List(猕猴桃, 无籽西瓜, 水晶葡萄)

在for循环中可以使用分号 (;) 来设置多个区间,它将迭代给定区间所有的可能值。以下示例代码演示了两个区间的循环实例:

for( a <- 1 to 3; b <- 1 to 3){
print( "a = " + a )
println( ", b = " + b )
}

输出结果如下所示:

a = 1, b = 1 
a = 1, b = 2
a = 1, b = 3
a = 2, b = 1
a = 2, b = 2
a = 2, b = 3
a = 3, b = 1
a = 3, b = 2
a = 3, b = 3

【示例】遍历二维数组。

 

// 处理多维数组
var myMatrix = Array.ofDim[Int](3,3)

// 创建矩阵
for (i <- 0 to 2) {
for ( j <- 0 to 2) {
myMatrix(i)(j) = j;
}
}

// 打印二维阵列
for (i <- 0 to 2; j <- 0 to 2) {
print(" " + myMatrix(i)(j));
if(j==2) println()
}

println("-------------------")

// 多维数组
val array = Array.ofDim[Int](2, 2)
array(0)(0) = 0
array(0)(1) = 1
array(1)(0) = 2
array(1)(1) = 3

for {
i <- 0 to 1
j <- 0 to 1
} println(s"($i)($j) = ${array(i)(j)}")

执行结果如下:

 0 1 2
0 1 2
0 1 2
------------------
(0)(0) = 0
(0)(1) = 1
(1)(0) = 2
(1)(1) = 3

【示例】编程输出九九乘法表。

// 九九乘法表 1
for(i <- 1 to 9) {
for(j <- 1 to i){
var ret = i * j
print(s"$i*$j=$ret\t")
}
println()
}

// 九九乘法表 2
for(i <- 1 to 9; j <- 1 to i) {
var ret = i * j
print(s"$i*$j=$ret\t")
if(i == j) {
println
}
}

输出结果如下:

1*1=1	
2*1=2 2*2=4
3*1=3 3*2=6 3*3=9
4*1=4 4*2=8 4*3=12 4*4=16
5*1=5 5*2=10 5*3=15 5*4=20 5*5=25
6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36
7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49
8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64
9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81
--------------
1*1=1
2*1=2 2*2=4
3*1=3 3*2=6 3*3=9
4*1=4 4*2=8 4*3=12 4*4=16
5*1=5 5*2=10 5*3=15 5*4=20 5*5=25
6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36
7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49
8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64
9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81

中断循环

Scala并没有提供break或continue语句来退出循环。那么如果需要break时我们该怎么做呢?有如下几个选项:

    1. 使用Boolean型的控制变量。

    1. 使用嵌套函数——可以从函数当中return。

    1. 使用Breaks对象中的break方法。

break方法使用如下面的示例代码所示:

import scala.util.control.Breaks._

var n = 15
breakable {
for(c <- "Spark Scala Storm") {
if(n == 10) {
println()
break
} else {
print(c)
}
n -= 1
}
}

输出内容如下:

import scala.util.control.Breaks._ 
n: Int = 15
Spark

循环中使用计数器

使用for-each循环有一个缺点,就是无法获取当前索引值。为此,可使用循环计数器。请看以下的代码:

    val a = Array("张三","李四","王老五")

// 循环计数
for (i <- 0 until a.length) {
println(s"$i:${a(i)}")
}

输出结果如下:

0:张三 
1:李四
2:王老五

Scala集合还提供了一个zipWithIndex方法可用于创建循环计数器:

    for ((e, index) <- a.zipWithIndex) {
println(s"$index: $e")
}

输出结果如下:

0:张三 
1:李四
2:王老五

循环中使用条件过滤

可以遍历的同时执行条件过滤:

// for语句
for (e <- 1 to 5) {
println(e)
}

// 只输出偶数
for (e <- 1 to 10 if e % 2 == 0) {
println(e)
}

// 迭代
val books = Array("Scala从入门到精通", "Groovy从入门到精通",
"Java从入门到精通", "24小时精通Scala", "24小时精通Java")

for(book <- books){
print(book + " || ")
}
println("\n---------------------------")

// 过滤
for(book<-books if book.contains("Scala")){
println(book)
}

Scala可以使用一个或多个 if 语句来过滤一些元素:

val numList = Array(1,2,3,4,5,6,7,8,9,10);

// for 循环
for( a <- numList
if a != 3; if a < 8 ){
println( "a = " + a );
}

输出结果如下:

a = 1 
a = 2
a = 4
a = 5
a = 6
a = 7

可以为嵌套循环通过if表达式添加条件:

for (i <- 1 to 3; j <- 1 to 3 if i != j) 
print ((10 * i + j) + " ")

println

// if表达式是否添加括号,结果无变化:
for (i <- 1 to 3; j <- 1 to 3 if (i != j))
print ((10 * i + j) + " ")

输出结果如下:

12 13 21 23 31 32 
12 13 21 23 31 32

【示例】在for条件表达式中使用过滤。

    // 打印所有的偶数
  for (i <- 1 to 10 if i % 2 == 0) println(i)

  // 也可写成下面这样
  for {
    i <- 1 to 10
    if i % 2 == 0
  } println(i)

  // 多条件
  for {
    i <- 1 to 10
    if i > 3
    if i < 6
    if i % 2 == 0
  } println(i)
© 版权声明
THE END
喜欢就支持一下吧
点赞202赞赏 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

夸夸
夸夸
还有吗!没看够!
取消
昵称表情代码图片

    暂无评论内容