Scala 循环语句
Scala 提供了多种循环结构,包括 for 循环、while 循环等。Scala 的循环具有函数式编程的特色,支持生成器、过滤器和推导式。
for 循环
基本 for 循环
scala
object BasicForLoop {
def main(args: Array[String]): Unit = {
// 基本范围循环
println("基本 for 循环:")
for (i <- 1 to 5) {
println(s"i = $i")
}
println("\nuntil 循环 (不包含结束值):")
for (i <- 1 until 5) {
println(s"i = $i")
}
println("\n步长循环:")
for (i <- 1 to 10 by 2) {
println(s"i = $i")
}
println("\n倒序循环:")
for (i <- 10 to 1 by -1) {
println(s"i = $i")
}
}
}遍历集合
scala
object CollectionIteration {
def main(args: Array[String]): Unit = {
val fruits = List("苹果", "香蕉", "橙子", "葡萄")
val numbers = Array(1, 2, 3, 4, 5)
println("遍历列表:")
for (fruit <- fruits) {
println(s"水果: $fruit")
}
println("\n遍历数组:")
for (num <- numbers) {
println(s"数字: $num")
}
println("\n带索引遍历:")
for ((fruit, index) <- fruits.zipWithIndex) {
println(s"第${index + 1}个水果: $fruit")
}
println("\n使用 indices:")
for (i <- fruits.indices) {
println(s"索引 $i: ${fruits(i)}")
}
}
}嵌套 for 循环
scala
object NestedForLoop {
def main(args: Array[String]): Unit = {
println("嵌套 for 循环 - 乘法表:")
for (i <- 1 to 3) {
for (j <- 1 to 3) {
print(s"${i * j}\t")
}
println()
}
println("\n使用分号的嵌套循环:")
for (i <- 1 to 3; j <- 1 to 3) {
println(s"($i, $j) = ${i * j}")
}
println("\n三层嵌套:")
for {
x <- 1 to 2
y <- 1 to 2
z <- 1 to 2
} {
println(s"($x, $y, $z)")
}
}
}带条件的 for 循环
scala
object ConditionalForLoop {
def main(args: Array[String]): Unit = {
val numbers = 1 to 20
println("偶数:")
for (num <- numbers if num % 2 == 0) {
println(num)
}
println("\n能被3整除的数:")
for (num <- numbers if num % 3 == 0) {
println(num)
}
println("\n多个条件:")
for {
num <- numbers
if num % 2 == 0
if num > 10
} {
println(s"大于10的偶数: $num")
}
println("\n字符串过滤:")
val words = List("hello", "world", "scala", "programming", "fun")
for (word <- words if word.length > 4) {
println(s"长单词: $word")
}
}
}for 推导式 (for comprehension)
scala
object ForComprehension {
def main(args: Array[String]): Unit = {
val numbers = 1 to 10
// 生成新的集合
val squares = for (num <- numbers) yield num * num
println(s"平方数: $squares")
val evenSquares = for {
num <- numbers
if num % 2 == 0
} yield num * num
println(s"偶数的平方: $evenSquares")
// 字符串处理
val words = List("hello", "world", "scala")
val upperWords = for (word <- words) yield word.toUpperCase
println(s"大写单词: $upperWords")
// 复杂的推导式
val coordinates = for {
x <- 1 to 3
y <- 1 to 3
if x != y
} yield (x, y)
println(s"坐标对 (x != y): $coordinates")
// 嵌套集合处理
val matrix = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9))
val flattenedDoubled = for {
row <- matrix
element <- row
} yield element * 2
println(s"扁平化并翻倍: $flattenedDoubled")
}
}while 循环
基本 while 循环
scala
object BasicWhileLoop {
def main(args: Array[String]): Unit = {
var i = 1
println("while 循环:")
while (i <= 5) {
println(s"i = $i")
i += 1
}
// 计算阶乘
var n = 5
var factorial = 1
var counter = 1
while (counter <= n) {
factorial *= counter
counter += 1
}
println(s"$n! = $factorial")
}
}do-while 循环
scala
object DoWhileLoop {
def main(args: Array[String]): Unit = {
var i = 1
println("do-while 循环:")
do {
println(s"i = $i")
i += 1
} while (i <= 5)
// 至少执行一次的示例
var input = 0
do {
println("请输入一个正数:")
input = scala.io.StdIn.readInt()
if (input <= 0) {
println("输入无效,请重新输入!")
}
} while (input <= 0)
println(s"您输入的正数是: $input")
}
}循环控制
break 和 continue (使用 Breaks)
scala
import scala.util.control.Breaks._
object LoopControl {
def main(args: Array[String]): Unit = {
println("使用 break:")
breakable {
for (i <- 1 to 10) {
if (i == 6) break()
println(s"i = $i")
}
}
println("\n使用 continue (跳过偶数):")
for (i <- 1 to 10) {
breakable {
if (i % 2 == 0) break() // 相当于 continue
println(s"奇数: $i")
}
}
println("\n嵌套循环中的 break:")
breakable {
for (i <- 1 to 5) {
for (j <- 1 to 5) {
if (i * j > 10) break()
println(s"$i * $j = ${i * j}")
}
}
}
}
}标签化的 break
scala
import scala.util.control.Breaks._
object LabeledBreak {
def main(args: Array[String]): Unit = {
println("标签化的 break:")
outer: breakable {
for (i <- 1 to 5) {
inner: breakable {
for (j <- 1 to 5) {
if (i == 3 && j == 3) {
println(s"在 ($i, $j) 处跳出外层循环")
break(outer)
}
println(s"($i, $j)")
}
}
}
}
println("外层循环结束")
}
}函数式循环替代方案
使用高阶函数
scala
object FunctionalLoops {
def main(args: Array[String]): Unit = {
val numbers = List(1, 2, 3, 4, 5)
println("使用 foreach:")
numbers.foreach(num => println(s"数字: $num"))
println("\n使用 map:")
val doubled = numbers.map(_ * 2)
println(s"翻倍: $doubled")
println("\n使用 filter:")
val evens = numbers.filter(_ % 2 == 0)
println(s"偶数: $evens")
println("\n使用 reduce:")
val sum = numbers.reduce(_ + _)
println(s"总和: $sum")
println("\n使用 fold:")
val product = numbers.fold(1)(_ * _)
println(s"乘积: $product")
println("\n使用 zipWithIndex:")
numbers.zipWithIndex.foreach { case (value, index) =>
println(s"索引 $index: $value")
}
}
}递归替代循环
scala
object RecursiveLoops {
// 递归计算阶乘
def factorial(n: Int): Int = {
if (n <= 1) 1
else n * factorial(n - 1)
}
// 尾递归计算阶乘
def factorialTailRec(n: Int): Int = {
@annotation.tailrec
def loop(n: Int, acc: Int): Int = {
if (n <= 1) acc
else loop(n - 1, n * acc)
}
loop(n, 1)
}
// 递归遍历列表
def printList[T](list: List[T]): Unit = list match {
case Nil => println("列表结束")
case head :: tail =>
println(s"元素: $head")
printList(tail)
}
// 递归计算斐波那契数列
def fibonacci(n: Int): Int = {
if (n <= 1) n
else fibonacci(n - 1) + fibonacci(n - 2)
}
// 尾递归斐波那契
def fibonacciTailRec(n: Int): Int = {
@annotation.tailrec
def loop(n: Int, prev: Int, curr: Int): Int = {
if (n == 0) prev
else loop(n - 1, curr, prev + curr)
}
loop(n, 0, 1)
}
def main(args: Array[String]): Unit = {
println(s"5! = ${factorial(5)}")
println(s"5! (尾递归) = ${factorialTailRec(5)}")
val list = List(1, 2, 3, 4, 5)
printList(list)
println(s"斐波那契数列第10项: ${fibonacci(10)}")
println(s"斐波那契数列第10项 (尾递归): ${fibonacciTailRec(10)}")
}
}实践示例
数字猜测游戏
scala
import scala.util.Random
import scala.io.StdIn
object NumberGuessingGame {
def main(args: Array[String]): Unit = {
val random = new Random()
val targetNumber = random.nextInt(100) + 1
var attempts = 0
var guessed = false
println("欢迎来到数字猜测游戏!")
println("我想了一个1到100之间的数字,请猜猜是多少?")
while (!guessed && attempts < 10) {
print("请输入您的猜测: ")
val guess = StdIn.readInt()
attempts += 1
if (guess == targetNumber) {
println(s"恭喜!您在第 $attempts 次尝试中猜对了!")
guessed = true
} else if (guess < targetNumber) {
println("太小了!")
} else {
println("太大了!")
}
if (!guessed && attempts < 10) {
println(s"您还有 ${10 - attempts} 次机会")
}
}
if (!guessed) {
println(s"游戏结束!正确答案是 $targetNumber")
}
}
}矩阵操作
scala
object MatrixOperations {
def printMatrix(matrix: Array[Array[Int]]): Unit = {
for (row <- matrix) {
for (element <- row) {
print(s"$element\t")
}
println()
}
}
def createMatrix(rows: Int, cols: Int): Array[Array[Int]] = {
val matrix = Array.ofDim[Int](rows, cols)
var counter = 1
for (i <- matrix.indices) {
for (j <- matrix(i).indices) {
matrix(i)(j) = counter
counter += 1
}
}
matrix
}
def transposeMatrix(matrix: Array[Array[Int]]): Array[Array[Int]] = {
val rows = matrix.length
val cols = matrix(0).length
val transposed = Array.ofDim[Int](cols, rows)
for (i <- matrix.indices) {
for (j <- matrix(i).indices) {
transposed(j)(i) = matrix(i)(j)
}
}
transposed
}
def main(args: Array[String]): Unit = {
println("创建 3x4 矩阵:")
val matrix = createMatrix(3, 4)
printMatrix(matrix)
println("\n转置矩阵:")
val transposed = transposeMatrix(matrix)
printMatrix(transposed)
}
}素数生成器
scala
object PrimeGenerator {
def isPrime(n: Int): Boolean = {
if (n < 2) return false
if (n == 2) return true
if (n % 2 == 0) return false
var i = 3
while (i * i <= n) {
if (n % i == 0) return false
i += 2
}
true
}
def generatePrimes(limit: Int): List[Int] = {
val primes = for {
num <- 2 to limit
if isPrime(num)
} yield num
primes.toList
}
def sieveOfEratosthenes(limit: Int): List[Int] = {
val isPrime = Array.fill(limit + 1)(true)
isPrime(0) = false
if (limit >= 1) isPrime(1) = false
for (i <- 2 to math.sqrt(limit).toInt) {
if (isPrime(i)) {
for (j <- i * i to limit by i) {
isPrime(j) = false
}
}
}
(for (i <- isPrime.indices if isPrime(i)) yield i).toList
}
def main(args: Array[String]): Unit = {
val limit = 50
println(s"使用试除法生成 $limit 以内的素数:")
val primes1 = generatePrimes(limit)
println(primes1.mkString(", "))
println(s"\n使用埃拉托斯特尼筛法生成 $limit 以内的素数:")
val primes2 = sieveOfEratosthenes(limit)
println(primes2.mkString(", "))
}
}性能考虑
- for 推导式 vs 命令式循环:for 推导式更函数式,但可能有性能开销
- 尾递归优化:使用
@tailrec注解确保尾递归优化 - 避免嵌套循环:考虑使用函数式方法如
flatMap - 使用 View:对于大集合,使用
view进行惰性求值
scala
object PerformanceConsiderations {
def main(args: Array[String]): Unit = {
val largeRange = 1 to 1000000
// 使用 view 进行惰性求值
val result = largeRange.view
.filter(_ % 2 == 0)
.map(_ * 2)
.take(10)
.toList
println(s"前10个偶数翻倍: $result")
}
}掌握循环结构对于编写高效的 Scala 程序至关重要,同时要学会在适当的时候使用函数式编程的替代方案。