Scala 新手实战三案例:从循环到条件,搞定基础编程场景

发布于:2025-09-15 ⋅ 阅读:(24) ⋅ 点赞:(0)

Scala 新手实战三案例:从循环到条件,搞定基础编程场景

对 Scala 新手来说,单纯记语法容易 “学完就忘”,而通过小而精的实战案例巩固知识点,是掌握语言的关键。本文精选三个高频基础场景 ——9 乘 9 乘法口诀表、成绩等级评定、整数约数查找,每个案例都覆盖 Scala 核心语法(循环、条件、集合、输入输出),并附带代码解析和运行验证,帮你真正理解 “代码为什么这么写”。

一、案例一:9 乘 9 乘法口诀表(掌握嵌套循环与字符串格式化)

1.1 需求分析

输出标准乘法口诀表:

  • 共 9 行,第i行包含i个乘法表达式(如第 3 行:1×3=3、2×3=6、3×3=9)

  • 表达式对齐,格式整洁(避免因数字位数导致错位)

1.2 完整代码(含注释)

object MultiplicationTable {​
  def main(args: Array[String]): Unit = {​
    // 外层循环:控制行数(i从1到9,闭区间用to)​
    for (i <- 1 to 9) {​
      // 内层循环:控制每行的列数(j从1到i,确保第i行有i个表达式)​
      for (j <- 1 to i) {​
        // 字符串插值(s"")+ 制表符(\t):既简化拼接,又保证对齐​
        print(s"$j×$i=${j * i}\t")​
      }​
      // 每行结束后换行​
      println()​
    }​
  }​
}

1.3 核心知识点拆解(新手必懂)

  1. Scala 的 for 循环特性
  • 1 to 9生成闭区间(包含 1 和 9),若用1 until 9则是左闭右开(包含 1,不包含 9),这里需用to才够 9 行。

  • 嵌套循环逻辑:外层i控制 “被乘数”(如第 3 行所有表达式的第二个数都是 3),内层j控制 “乘数”(从 1 递增到i)。

  1. 字符串插值(s"")

    相比 Java 的"$j×$i=" + (j*i),Scala 的s""可直接在字符串中嵌入变量($变量名)或表达式(${表达式}),代码更简洁,且不易出错。

  2. 制表符(\t)的作用

    每个表达式后加\t,会让输出按 “制表位” 对齐(无论j*i是 1 位还是 2 位,都能保持列对齐),最终输出格式整齐。

1.4 运行结果(IDEA 中直接右键运行)

在这里插入图片描述

二、案例二:成绩等级评定(掌握条件表达式嵌套与返回值特性)

2.1 需求分析

根据输入的整数成绩(0-100 分)评定等级:

  • 90 分及以上 → A(优秀)

  • 60-89 分 → B(及格)

  • 60 分以下 → C(不及格)

  • 需处理边界值(如 60 分、90 分),且代码逻辑清晰。

2.2 两种实现方案(对比学习)

Scala 的条件表达式是 “有返回值的”,因此有两种常见写法,可根据场景选择:

方案 1:嵌套 if-else(适合复杂多层判断)
object GradeEvaluator {​
  def main(args: Array[String]): Unit = {​
    // 测试多个分数(用List存储,便于批量验证)​
    val scores = List(95, 80, 60, 55, 100, 0)​
    ​
    // 遍历分数,调用评级函数并打印结果​
    scores.foreach(score => {​
      val grade = getGradeByNested(score)​
      println(s"分数 $score → 等级 $grade")​
    })​
  }​
​
  // 嵌套if-else实现:先判断是否及格,再判断是否优秀​
  def getGradeByNested(score: Int): Char = {​
    if (score >= 60) { // 第一层:是否及格​
      if (score >= 90) 'A' // 第二层:及格中是否优秀​
      else 'B' // 及格但不优秀​
    } else {​
      'C' // 不及格​
    }​
  }​
}
方案 2:else if(适合扁平多层判断)

若判断条件是 “互斥且有序” 的,用else if更简洁,逻辑更直观:

// 新增else if实现的函数(替换上述getGradeByNested即可)​
def getGradeByElseIf(score: Int): Char = {​
  if (score >= 90) 'A'       // 优先级1:先判断最高等级​
  else if (score >= 60) 'B'  // 优先级2:再判断及格​
  else 'C'                   // 优先级3:最后判断不及格​
}

2.3 核心知识点拆解

  1. Scala 条件表达式的 “返回值特性”

    Java 中if-else是 “语句”(无返回值,需用return手动返回),而 Scala 中if-else是 “表达式”(每个分支的结果就是返回值,无需return)。

    例:val grade = if (score >=90) 'A' else 'B' 完全合法,grade会直接接收分支结果。

  2. 两种判断逻辑的选择场景

  • 嵌套if-else:适合 “先过滤大类,再细分小类” 的场景(如先判断 “是否成年”,再判断 “是否满 30 岁”)。

  • else if:适合 “按优先级排序” 的判断(如成绩等级从高到低判断),代码更扁平,可读性更高。

  1. List 遍历与 foreach

    scores.foreach(...)替代for (score <- scores),是 Scala 函数式编程的初步体现(将 “遍历” 逻辑封装为方法),代码更简洁。

2.4 运行结果

两种方案输出一致,边界值处理正确:

分数 95 → 等级 A

分数 80 → 等级 B

分数 60 → 等级 B

分数 55 → 等级 C

分数 100 → 等级 A

分数 0 → 等级 C

三、案例三:整数约数查找(掌握输入输出、特殊处理与集合筛选)

3.1 需求分析

  • 接收用户输入的整数(支持正、负、0)

  • 找出该整数的所有约数,存储到数组中

  • 打印数组(格式友好,如[1, 2, 3, 6]

  • 特殊处理:0 有无限个约数,需提示用户。

3.2 完整代码(含异常场景处理)

object DivisorFinder {​
  def main(args: Array[String]): Unit = {​
  def findDivisors(n: Int): Array[Int] = {​
    // 特殊处理1:0有无限个约数,返回空数组并提示​
    if (n == 0) {​
      println("⚠️  注意:0有无限个约数,无法全部列出")​
      return Array.empty[Int] // 返回空数组​
    }​
​
    // 特殊处理2:负数的约数与绝对值的约数相同,先取绝对值​
    val absNum = math.abs(n)​
​
    // 筛选约数:从1到absNum,过滤出能整除absNum的数​
    // (1 to absNum):生成整数序列;filter:筛选符合条件的元素;toArray:转为数组​
    (1 to absNum).filter(i => absNum % i == 0).toArray​
  }​
}

3.3 核心知识点拆解

  1. Scala 标准输入(StdIn)

    scala.io``.StdIn.readInt()直接读取整数输入,无需像 Java 那样创建Scanner对象,代码更简洁。若需读取字符串,可用readLine()

  2. 特殊场景处理

  • 0 的约数:数学上 0 能被任意非零整数整除,因此约数无限,程序主动提示并返回空数组,避免逻辑错误。

  • 负数的约数:约数是 “整除” 的概念,与正负无关(如 - 12 的约数和 12 的约数相同),用math.abs(n)取绝对值,统一处理逻辑。

  1. 集合筛选(filter)与类型转换
  • (1 to absNum)生成 “整数序列”(Range 类型),不是数组。

  • filter(i => absNum % i == 0):遍历序列,保留 “能整除 absNum” 的元素(i 是约数的条件)。

  • toArray:将筛选后的序列转为数组,满足 “存储到数组” 的需求。

  1. 数组格式化打印(mkString)

    数组默认打印格式是[I@6d06d69c(内存地址),用mkString(prefix, separator, suffix)可自定义格式:

  • prefix:开头字符(如[

  • separator:元素间分隔符(如,

  • suffix:结尾字符(如]

3.4 运行结果(多场景测试)

场景 1:输入正数(如 12)
请输入一个整数:

12

整数 12 的所有约数:\[1, 2, 3, 4, 6, 12]
场景 2:输入负数(如 - 18)
请输入一个整数:

-18

整数 -18 的所有约数:\[1, 2, 3, 6, 9, 18]
场景 3:输入 0
请输入一个整数:

0

⚠️  注意:0有无限个约数,无法全部列出

整数 0 的所有约数:\[]

四、三个案例的共性 Scala 特性总结

通过三个案例,你能发现 Scala 的核心设计思想,这些特性会贯穿后续所有编程场景:

特性 案例体现 优势
表达式导向 条件表达式返回值、for 循环生成序列 无需return,代码简洁,减少冗余
函数式编程初步 List.foreachRange.filter 封装遍历 / 筛选逻辑,代码更易读
简洁的 API 设计 StdIn.readInt()mkStringmath.abs 避免重复造轮子,开发效率高
类型转换便捷 toArrayto/until生成序列 集合间转换灵活,满足不同场景需求
异常场景友好处理 0 的约数提示、负数绝对值处理 程序鲁棒性强,减少崩溃风险

五、新手进阶建议:基于案例扩展练习

学会 “修改代码” 比 “看懂代码” 更重要,推荐几个扩展方向,帮你深化理解:

  1. 乘法表扩展

    输出 “倒序乘法表”(从 9 行到 1 行),只需将外层循环改为for (i <- 9 to 1 by -1)by -1表示步长为 - 1,反向遍历)。

  2. 成绩等级扩展

    增加 D 级(40-59 分)和 E 级(40 分以下),用else if补充判断逻辑,测试边界值(如 40 分、59 分)。

  3. 约数扩展

    给约数数组去重(如输入 16,约数是 [1,2,4,8,16],无重复,可模拟输入重复场景)、按降序排序(在toArray后加.sorted(Ordering[Int].reverse))。

结语

Scala 的学习核心是 “先实战,再归纳”。这三个案例覆盖了新手最常用的语法场景,建议你在 IDEA 中逐行敲写代码,尝试修改逻辑(如改循环条件、加判断分支),观察输出变化 —— 只有动手实践,才能真正掌握 Scala 的灵活与高效。后续可深入学习 Scala 的集合框架(List、Map)和函数式编程(匿名函数、高阶函数),逐步解锁更多高级特性!


网站公告

今日签到

点亮在社区的每一天
去签到