第八章 集合与包 示例代码

浙江传媒学院 · 仓颉面向对象程序设计 · 基于 CangStream 框架构建

示例程序
27 个
程序实例
5 个
代码合计
32 个

一、ArrayList(8.2)

例8-1 访问 ArrayList 所有元素

8.2.2:创建 ArrayList 并使用 for-in 遍历所有元素。

package demo
import std.collection.*
main() {
    let list = ArrayList<Int64>([0, 1, 2])
    for (i in list) {
        println("The element is ${i}")
    }
}

例8-2 获取 ArrayList 的大小

8.2.2:使用 size 属性获取 ArrayList 中元素个数,if-else 判断是否为空。

package demo
import std.collection.*
main() {
    let list = ArrayList<Int64>([0, 1, 2])
    if (list.size == 0) {
        println("This is an empty arraylist")
    } else {
        println("The size of arraylist is ${list.size}")
    }
}

例8-3 访问指定位置的元素

8.2.2:通过下标索引访问 ArrayList 中指定位置的元素。

package demo
import std.collection.*
main() {
    let list = ArrayList<Int64>([0, 1, 2])
    let a = list[0]  // a == 0
    let b = list[1]  // b == 1
    println(
        "第一个元素是 ${a},第二个元素是 ${b}"
        )
}

例8-4 ArrayList 容量预分配

8.2.3:使用构造参数和 reserve() 方法预分配 ArrayList 容量。

package demo
import std.collection.*
main() {
    let list = ArrayList<Int64>(100)  // 一次性分配空间
    for (i in 0..100) {
        list.add(i)  // 不会触发空间重新分配
    }    
    list.reserve(100)  // 准备更多空间
    for (i in 0..100) {
        list.add(i)  // 不会触发空间重新分配
    }
}

二、HashSet(8.3)

例8-5 从数据中去除重复元素

8.3.1:将 Array 转换为 HashSet 实现数据去重。

package demo
import std.collection.*
main() {
    // 创建一个包含重复元素的数组
    let numbers = [1, 2, 2, 3, 4, 4, 5]
    // 将数组转换为 HashSet,自动去除重复的元素
    let uniqueNumbers = HashSet<Int64>(numbers)
    // 打印去重后的集合
    println(uniqueNumbers)  // 输出: [1, 2, 3, 4, 5]
}

例8-6 判断 HashSet 是否包含某个元素

8.3.1:使用 contains() 方法检查元素是否在 HashSet 中。

package demo
import std.collection.*
main() {
    // 创建一个 HashSet
    let set = HashSet<Int64>([1, 2, 3, 4, 5])
    // 检查集合中是否包含元素 3
    let isContained = set.contains(3)
    println(isContained)  // 输出: true
    // 检查集合中是否包含元素 6
    let isContained2 = set.contains(6)
    println(isContained2)  // 输出: false
}

例8-7 并集、交集、差集运算

8.3.1:HashSet 的 union、intersection 和 difference 集合运算。

package demo
import std.collection.*
main() {
    // 创建两个 HashSet
    let set1 = HashSet<Int64>([1, 2, 3, 4])
    let set2 = HashSet<Int64>([3, 4, 5, 6])
    // 计算并集
    var unionSet = HashSet<Int>(set1)
    for (item in set2) {
    unionSet.add(item)}
    println("Union: ${unionSet}")  // 输出: Union: [1, 2, 3, 4, 5, 6]
    // 计算交集   
    var intersectionSet = HashSet<Int>()
    for (item in set1) {
    if (set2.contains(item)) {
        intersectionSet.add(item)
    }}
    println("Intersection: ${intersectionSet}")  // 输出: Intersection: [3, 4]
    // 计算差集  
    var differenceSet = HashSet<Int>()
    for (item in set1) {
        if (!set2.contains(item)) {
            differenceSet.add(item)  // 使用 add 替代 put
        }
    }
    println("Difference: ${differenceSet}")  // 输出: Difference: [1, 2]
}


例8-8 存储唯一标识符 ID

8.3.1:使用 HashSet 对用户 ID 进行去重存储。

package demo
import std.collection.*
main() {
    // 创建一个 HashSet 用来存储用户的唯一 ID
    let userIDs = HashSet<Int64>([101, 102, 103, 104])
    // 尝试添加重复的 ID
    userIDs.add(103)  // 不会添加,因为 103 已经存在
    // 打印 HashSet,验证去重效果
    println(userIDs)  // 输出: [101, 102, 103, 104]
}

例8-9 使用规则函数创建 HashSet

8.3.1:使用规则函数生成 0 到 9 的整数的平方,初始化 HashSet。

package demo
import std.collection.*
main() {
    // 使用规则函数创建 HashSet,其中每个元素是元素的平方
    let squaredSet = HashSet<Int64>(10, {x: Int64 => x * x})
    // 打印 HashSet,元素为 0 到 9 的平方
    println(squaredSet)  // 输出: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
}

例8-10 遍历 HashSet 中的所有元素

8.3.2:使用 for-in 循环遍历 HashSet 的所有元素。

package demo
import std.collection.*
main() {
    // 创建一个 HashSet,包含 0, 1, 2
    let mySet = HashSet<Int64>([0, 1, 2])    
    // 使用 for-in 循环遍历 HashSet 的元素
    for(i in mySet) {
        println("The element is ${i}")
    }
}

例8-11 使用 size 属性获取元素个数

8.3.2:通过 size 属性判断 HashSet 是否为空及元素数量。

package demo
import std.collection.*
main() {
    // 创建一个 HashSet,包含 0, 1, 2
    let mySet = HashSet<Int64>([0, 1, 2])    
    // 获取并输出 HashSet 的大小
    if (mySet.size == 0) {
        println("This is an empty hashset")
    } else {
        println("The size of hashset is ${mySet.size},all element:${mySet}")
    }
}

例8-12 判断 HashSet 是否包含某个元素

8.3.2:使用 contains() 方法逐项检查元素是否存在。

package demo
import std.collection.*
main() {
    // 创建一个 HashSet,包含 0, 1, 2
    let mySet = HashSet<Int64>([0, 1, 2]) 
    // 检查元素是否存在于 HashSet 中
    let a = mySet.contains(0) // a == true
    let b = mySet.contains(-1) // b == false 
    // 输出检查结果
    println("Contains 0: ${a}")
    println("Contains -1: ${b}")
}

例8-13 添加单个元素

8.3.3:使用 add() 方法向 HashSet 添加元素,重复元素不会被添加。

package demo
import std.collection.*
main() {
    // 创建一个空的 HashSet
    let mySet = HashSet<Int64>()    
    // 向 HashSet 添加元素
    mySet.add(0)  // mySet contains: 0
    mySet.add(0)  // 无效,因为 0 已经存在
    mySet.add(1)  // mySet contains: 0, 1
    // 输出结果
    for (i in mySet) {
        println("The element is ${i}")
    }
}

例8-14 批量添加元素

8.3.3:使用 add(all:) 方法从 Array 批量添加元素到 HashSet。

package demo
import std.collection.*
main() {
    // 创建一个 HashSet 和一个 Array
    let mySet = HashSet<Int64>()
    let li = [1,2, 3]    
    // 将 Array 中的元素批量添加到 HashSet
    mySet.add(0)  // mySet contains: 0
    mySet.add(1)  // mySet contains: 0, 1
    mySet.add(all: li)// mySet contains: 0, 1, 2, 3
    // 输出结果
    println("All in myset: ${mySet}")   
}

例8-15 删除元素

8.3.3:使用 remove() 方法从 HashSet 中删除指定元素。

package demo
import std.collection.*
main() {
    // 创建一个 HashSet,包含元素 0, 1, 2, 3
    let mySet = HashSet<Int64>([0, 1, 2, 3])        
    // 删除元素 1
    mySet.remove(1)  // mySet contains: 0, 2, 3    
    // 输出结果
    println("All in myset: ${mySet}")  
}

例8-16 HashSet 可迭代器遍历与引用特性

8.3.3:HashSet 是引用类型,两个变量引用同一集合时共享数据。

package demo
import std.collection.*
main() {
    // 创建一个 HashSet,并将其赋值给另一个引用
    let set1 = HashSet<Int64>([0, 1, 2])
    let set2 = set1 // set2 是 set1 的引用 
    // 向 set2 添加一个元素
    set2.add(3) // set1 和 set2 都包含元素: 0, 1, 2, 3 
    // 输出结果
    for (i in set1) {
       println("set1 contains: ${i}")
    }
    for (i in set2) {
       println("set2 contains: ${i}")
    }
}

三、HashMap(8.4)

例8-17 创建空的 HashMap

8.4.1:使用不同的构造函数创建 HashMap,检查 isEmpty 状态。

package demo
import std.collection.*
main() {
     // 创建一个空的 HashMap,键类型为 String,值类型为 Int64
    let map = HashMap<String, Int64>() 
    println("The map is empty: ${map.size == 0}") // 输出:true
}

例8-18 用多参数构造成数组初始化

8.4.1:使用元组数组构造 HashMap 并用 for-in 遍历键值对。

package demo
import std.collection.*
main() {
    let map = HashMap<String, Int64>([("a", 0), ("b", 1), ("c", 2)])
    for ((k, v) in map) {
       println("The key is ${k}, the value is ${v}")
    }
}

例8-19 获取 HashMap 的大小

8.4.1:使用 size 属性获取 HashMap 中键值对的数量。

package demo
import std.collection.*
main() {
    let map = HashMap<String, Int64>([("a", 0), ("b", 1), ("c", 2)])
    println("The size of hashmap is ${map.size}") // 输出:3
}

例8-20 判断某个键是否在字典中

8.4.2:使用 contains() 方法判断 HashMap 中是否存在指定的键。

package demo
import std.collection.*

main() {
    let map = HashMap<String, Int64>([("a", 0), ("b", 1), ("c", 2)])
    let a = map.contains("a")  // true
    let b = map.contains("d")  // false
    println("Contains 'a': ${a}")
    println("Contains 'd': ${b}")
}

例8-21 修改 HashMap

8.4.2:通过下标赋值修改已有键的值。

package demo
import std.collection.*
main() {
    let map = HashMap<String, Int64>([("a", 0), ("b", 1), ("c", 2)])
    map["a"] = 3  // 修改键 "a" 对应的值为 3
    println("Updated map: ${map}") // 输出:("a", 3), ("b", 1), ("c", 2)
}

例8-22 用 add() 方法增加或修改键值对

8.4.2:使用 add() 向 HashMap 中增加新的键值对。

package demo
import std.collection.*
main() {
    let map = HashMap<String, Int64>()
    map.add("a", 0)  // 添加键值对 ("a", 0)
    map.add("b", 1)  // 添加键值对 ("b", 1)
    println("Map after putting: ${map}")
}

例8-23 用 remove() 方法删除键值对

8.4.2:使用 remove() 从 HashMap 中删除指定键的条目。

package demo
import std.collection.*
main() {
    let map = HashMap<String, Int64>([("a", 0), ("b", 1), ("c", 2)])
    map.remove("b")  // 删除键 "b" 对应的元素
    println("Map after removal: ${map}")  // 输出:("a", 0), ("c", 2)
}

例8-24 用 add(all:) 属性增加键值对

8.4.2:使用 add(all:) 将一个 HashMap 的所有键值对合并到另一个中。

package demo
import std.collection.*
main() {
    let map = HashMap<String, Int64>([("a", 0), ("b", 1)])
    let map2 = HashMap<String, Int64>([("c", 2), ("d", 3)])
    map.add(all: map2) // 将 map2 中的所有键值对添加到 map 中
    println("Map after addAll: ${map}")  // 输出:("a", 0), ("b", 1), ("c", 2), ("d", 3)
}

例8-25 HashMap 的引用类型特性

8.4.2:HashMap 是引用类型,赋值后两个变量共享同一数据。

package demo
import std.collection.*
main() {
    let map1 = HashMap<String, Int64>([("a", 0), ("b", 1), ("c", 2)])
    let map2 = map1  // map2 是 map1 的引用
    map2["a"] = 3  // 修改 map2 中的键 "a" 的值    
    println("map1 after change: ${map1}")  // 输出:("a", 3), ("b", 1), ("c", 2)
    println("map2 after change: ${map2}")  // 输出:("a", 3), ("b", 1), ("c", 2)
}

四、使用 HashMap 进行数据管理(8.4.3)

例8-26-1 水果进销管理程序 1

使用 HashMap 来存储商品名称和数量,初始化库存并输出。

package demo
import std.collection.*
main() {
    // 使用 HashMap 来存储商品名称和数量
    var inventory = HashMap<String, Int64>()    
    inventory.add("苹果", 100)
    inventory.add("香蕉", 50)
    inventory.add("橙子", 75)
    inventory.add("西瓜", 30)
    inventory.add("葡萄", 60)  
    println("目前库存情况:${inventory}")  
}   

例8-26-2 水果进销管理程序 2

编写 updateStock() 函数,更新水果名称和库存数量。

package demo
import std.collection.*
// 更新库存(增加或减少)
func updateStock(inventory: HashMap<String, Int64>, item: String, change: Int64) {
if (inventory.contains(item)) {  // 更新水果是否满足更新条件
   for ((key, value) in inventory) {     //遍历inventory
      if (key == item) {                // 找到需要更新的健
      let currentStock = value      // 解包更新的值
      let newStock = currentStock + change  //更新值
      inventory.add(item, newStock)       //更新库存
      let operation = if (change > 0) { "增加" } else { "减少" }
      let changeAmount = if (change > 0) { change } else { -change }
      println("库存更新: ${item} ${operation} ${changeAmount} 个,当前库存: ${newStock}")//输出更新结果
            }        }        } 
      else {    
       println("错误: 商品 ${item} 不存在,无法更新库存")
   }
}
main() {
   var inventory = HashMap<String, Int64>()    
   inventory.add("苹果", 100)
    inventory.add("香蕉", 50)
    inventory.add("橙子", 75)
    inventory.add("西瓜", 30)
    inventory.add("葡萄", 60)  
    println("目前库存情况:${inventory}")  
    updateStock(inventory, "苹果", -20)  
}   

例8-26-3 水果进销管理程序 3

编写 searchItem() 函数,查询指定水果的库存信息。

package demo
import std.collection.*
// 查找商品
func searchItem(inventory: HashMap<String, Int64>, item: String) {
    if (inventory.contains(item)) {
        // 通过遍历找到对应的值
        for ((key, value) in inventory) {
            if (key == item) {
                println("查找结果: 商品 ${item} 库存数量为 ${value}")
                return
            }
        }
    } else {
        println("查找结果: 商品 ${item} 未找到")
    }
}
main() {
   var inventory = HashMap<String, Int64>()    
   inventory.add("苹果", 100)
    inventory.add("香蕉", 50)
    inventory.add("橙子", 75)
    inventory.add("西瓜", 30)
    inventory.add("葡萄", 60)  
    println("目前库存情况:${inventory}")  
     searchItem(inventory, "橙子")  
} 

例8-26-4 水果进销管理程序 4

编写 calculateStatistics() 函数,统计库存总量、均值、最大/最小值。

package demo
import std.collection.*
// 计算库存统计信息
func calculateStatistics(inventory: HashMap<String, Int64>) {
    if (inventory.size == 0) {
        println("库存为空,无法统计")
        return
    }    
    var totalItems: Int64 = 0
    var maxQuantity: Int64 = 0
    var minQuantity: Int64 = Int64.Max
    var maxItem: String = ""
    var minItem: String = ""    
    for ((item, quantity) in inventory) {
        totalItems += quantity        
        if (quantity > maxQuantity) {
            maxQuantity = quantity
            maxItem = item        }
        
        if (quantity < minQuantity) {
            minQuantity = quantity
            minItem = item
        }
    }    
    var averageQuantity = totalItems / Int64(inventory.size)    
    println("库存统计信息:")
    println("商品种类: ${inventory.size}")
    println("商品总数: ${totalItems}")
    println("平均库存: ${averageQuantity}")
    println("库存最多: ${maxItem} (${maxQuantity})")
    println("库存最少: ${minItem} (${minQuantity})")
    println("")
}
main() {
   var inventory = HashMap<String, Int64>()    
   inventory.add("苹果", 100)
    inventory.add("香蕉", 50)
    inventory.add("橙子", 75)
    inventory.add("西瓜", 30)
    inventory.add("葡萄", 60)  
    println("目前库存情况:${inventory}")  
     calculateStatistics(inventory)  
}

五、自定义类型的集合处理(8.5)

例8-27-1 自定义类型用于 HashSet(错误版本)

Student 未实现 Hashable 和 Equatable 接口,直接用于 HashSet 会导致编译错误。

 //错误程序   
package demo
import std.collection.*
class Student {
    var name: String
    var age: Int64
      init(name: String, age: Int64) {
        this.name = name
        this.age = age
    }  
}
main() {
    var studentSet = HashSet<Student>()
    studentSet.add(Student("张三", 25))
    studentSet.add(Student("李四", 24))
    studentSet.add(Student("张三", 25)) 
    println("\n今天注册的同学是:")
    for (person in studentSet) {
        println(student.toString())
    }
}

例8-27-2 自定义类型用于 HashSet(正确版本)

Student 实现 Hashable 及 Equatable 接口,重载 hashCode() 和 ==,正确使用 HashSet。

package demo
import std.collection.*
class Student <: Hashable & Equatable<Student> {
    var name: String
    var age: Int64
    // 带参构造
    init(name: String, age: Int64) {
        this.name = name
        this.age = age
    }
    // 实现 Hashable 接口
    public func hashCode(): Int64 {
        return name.hashCode() + age.hashCode()
    }
    // 实现 Equatable 接口
    public operator func ==(other: Student): Bool {
        return this.name == other.name && this.age == other.age
    }
    // toString
    public func toString(): String {
        return "Student(${name}, ${age})"
    }
}
main() {
    var personSet = HashSet<Student>()
    personSet.add(Student("张三", 25))
    personSet.add(Student("李四", 24))
    personSet.add(Student("张三", 25)) // 不会重复添加
    println("\n今天注册的同学是:")
    for (person in personSet) {
        println(person.toString())
    }
}

六、程序示例(8.7)

示例1 用对象数组实现学生成绩管理

struct Student + class GradeManager,使用 Array 存储学生信息,计算平均分、查找最高分、统计及格人数。

package demo
// 学生成绩数据结构
struct Student {
    let name: String
    let score: Int64    
    public init(name: String, score: Int64) {
        this.name = name
        this.score = score
    }
}
// 成绩管理系统
class GradeManager {
    private let students: Array<Student>    
    public init(students: Array<Student>) {
        this.students = students
    }    
    // 计算平均分
    public func averageScore(): Float64 {
        if (students.size == 0) {
            return 0.0
        }        
        var total = 0
        for (student in students) {
            total += student.score
        }        
        return Float64(total) / Float64(students.size)
    }    
    // 找出最高分学生
    public func topStudent(): Option<Student> {
        if (students.size == 0) {
            return None<Student>
        }        
        var topStudent = students[0]
        for (student in students) {
            if (student.score > topStudent.score) {
                topStudent = student
            }
        }        
        return Some<Student>(topStudent)
    }    
    // 统计及格人数
    public func passCount(passingScore: Int64): Int64 {
         var count = 0
        for (student in students) {
            if (student.score >= passingScore) {
                count += 1
            }
        }
        return count
    }
}
// 使用示例
main(): Int64 {
    let students: Array<Student> = [
        Student("张三", 85),
        Student("李四", 92),
        Student("王五", 78),
        Student("赵六", 56),
        Student("钱七", 94)
    ]    
    let manager = GradeManager(students)    
    println("平均分: ${manager.averageScore()}")
    println("及格人数: ${manager.passCount(60)}")    
    match (manager.topStudent()) {
        case Some(student) => println("最高分: ${student.name} - ${student.score}")
        case None => println("没有学生数据")
    }    
    return 0
}

示例2 基于 HashMap 的学生成绩管理系统

Student 结构体 + HashMap 存储学生信息和成绩,支持添加/查询/更新/删除/统计等完整功能。

package demo
import std.collection.*

// 学生信息结构体
struct Student {
    var id: String
    var name: String
    var className: String
    var grades: HashMap<String, Int64>  // 科目 -> 成绩
    
    // 构造函数
    init(id: String, name: String, className: String) {
        this.id = id
        this.name = name
        this.className = className
        this.grades = HashMap<String, Int64>()
    }
    
    // 计算平均分
    func getAverage(): Float64 {
        if (this.grades.size == 0) {
            return 0.0
        }
        var total: Int64 = 0
        for ((_, grade) in this.grades) {
            total += grade
        }
        return Float64(total) / Float64(this.grades.size)
    }
}

main() {
    println("=== 仓颉语言HashMap学生成绩管理系统 ===\n")
    
    // 核心HashMap:学号 -> 学生对象
    var students = HashMap<String, Student>()
    
    // 辅助HashMap:姓名 -> 学号(用于按姓名查找)
    var nameToId = HashMap<String, String>()
    
    println("1. 添加学生信息...")
    
    // 添加学生信息的函数调用
    addStudent(students, nameToId, "2024001", "张三", "高一(1)班")
    addStudent(students, nameToId, "2024002", "李四", "高一(1)班")
    addStudent(students, nameToId, "2024003", "王五", "高一(2)班")
    
    println("\n2. 添加成绩信息...")
    
    // 为张三添加成绩
    addGradeToStudent(students, "2024001", "数学", 95)
    addGradeToStudent(students, "2024001", "语文", 88)
    addGradeToStudent(students, "2024001", "英语", 92)
    println("为张三添加了数学、语文、英语成绩")
    
    // 为李四添加成绩
    addGradeToStudent(students, "2024002", "数学", 87)
    addGradeToStudent(students, "2024002", "语文", 91)
    addGradeToStudent(students, "2024002", "物理", 85)
    println("为李四添加了数学、语文、物理成绩")
    
    // 为王五添加成绩
    addGradeToStudent(students, "2024003", "数学", 92)
    addGradeToStudent(students, "2024003", "语文", 89)
    addGradeToStudent(students, "2024003", "物理", 94)
    addGradeToStudent(students, "2024003", "化学", 88)
    println("为王五添加了数学、语文、物理、化学成绩")
    
    println("\n3. HashMap核心操作演示...")
    
    // 演示按学号查找学生
    println("\n--- 按学号查找学生 ---")
    searchStudentById(students, "2024001")
    
    // 演示按姓名查找学生
    println("\n--- 按姓名查找学生 ---")
    searchStudentByName(students, nameToId, "李四")
    
    println("\n4. 系统统计信息...")
    calculateStatistics(students)
    
    println("\n5. 成绩管理操作...")
    
    // 更新成绩
    updateGrade(students, "2024001", "数学", 98)
    
    // 删除学生
    removeStudent(students, nameToId, "2024003")
    
    println("\n6. 遍历所有学生信息...")
    displayAllStudents(students)
    
    println("\n7. 特殊查询...")
    
    // 查找优秀学生(平均分90以上)
    findExcellentStudents(students, 90.0)
    
    // 查找某科目成绩
    findStudentsBySubject(students, "数学")
    
    println("\n=== 学生成绩管理系统演示完成 ===")
}

// 添加学生
func addStudent(students: HashMap<String, Student>, nameToId: HashMap<String, String>, 
                id: String, name: String, className: String) {
    if (students.contains(id)) {
        println("警告: 学号 ${id} 已存在!")
        return
    }
    
    var student = Student(id, name, className)
    students.add(id, student)
    nameToId.add(name, id)
    println("添加学生: ${name} (${id}) - ${className}")
}

// 为学生添加成绩
func addGradeToStudent(students: HashMap<String, Student>, studentId: String, 
                       subject: String, grade: Int64) {
    if (students.contains(studentId)) {
        // 通过遍历找到学生并添加成绩
        for ((id, student) in students) {
            if (id == studentId) {
                student.grades.add(subject, grade)
                return
            }
        }
    } else {
        println("错误: 学号 ${studentId} 不存在")
    }
}

// 按学号查找学生
func searchStudentById(students: HashMap<String, Student>, studentId: String) {
    if (students.contains(studentId)) {
        for ((id, student) in students) {
            if (id == studentId) {
                println("找到学生: ${student.name}, 班级: ${student.className}")
                println("该学生成绩:")
                for ((subject, grade) in student.grades) {
                    println("  ${subject}: ${grade}分")
                }
                println("平均分: ${student.getAverage()}分")
                return
            }
        }
    } else {
        println("未找到学号为 ${studentId} 的学生")
    }
}

// 按姓名查找学生
func searchStudentByName(students: HashMap<String, Student>, nameToId: HashMap<String, String>, 
                         name: String) {
    if (nameToId.contains(name)) {
        // 通过遍历找到学号
        for ((studentName, studentId) in nameToId) {
            if (studentName == name) {
                println("找到学生: ${name} (学号: ${studentId})")
                searchStudentById(students, studentId)
                return
            }
        }
    } else {
        println("未找到姓名为 ${name} 的学生")
    }
}

// 更新成绩
func updateGrade(students: HashMap<String, Student>, studentId: String, 
                 subject: String, newGrade: Int64) {
    if (students.contains(studentId)) {
        for ((id, student) in students) {
            if (id == studentId) {
                var oldGrade: Int64 = 0
                var hasOldGrade = false
                
                // 查找旧成绩
                for ((sub, grade) in student.grades) {
                    if (sub == subject) {
                        oldGrade = grade
                        hasOldGrade = true
                        break
                    }
                }
                
                student.grades.add(subject, newGrade)
                if (hasOldGrade) {
                    println("更新成绩: ${student.name} 的 ${subject} 从 ${oldGrade} 更新为 ${newGrade}")
                } else {
                    println("添加成绩: ${student.name} 的 ${subject} 成绩为 ${newGrade}")
                }
                return
            }
        }
    } else {
        println("错误: 学号 ${studentId} 不存在")
    }
}

// 删除学生
func removeStudent(students: HashMap<String, Student>, nameToId: HashMap<String, String>, 
                   studentId: String) {
    if (students.contains(studentId)) {
        var studentName = ""
        
        // 找到学生姓名
        for ((id, student) in students) {
            if (id == studentId) {
                studentName = student.name
                break
            }
        }
        
        students.remove(studentId)
        if (studentName != "") {
            nameToId.remove(studentName)
        }
        println("已删除学生: ${studentName} (${studentId})")
    } else {
        println("删除失败: 学号 ${studentId} 不存在")
    }
}

// 计算系统统计信息
func calculateStatistics(students: HashMap<String, Student>) {
    println("学生总数: ${students.size}")
    
    if (students.size == 0) {
        println("系统中没有学生数据")
        return
    }
    
    var totalGrades: Int64 = 0
    var gradeCount: Int64 = 0
    var maxGrade: Int64 = 0
    var minGrade: Int64 = 100
    
    for ((_, student) in students) {
        for ((_, grade) in student.grades) {
            totalGrades += grade
            gradeCount += 1
            if (grade > maxGrade) {
                maxGrade = grade
            }
            if (grade < minGrade) {
                minGrade = grade
            }
        }
    }
    
    if (gradeCount > 0) {
        var overallAverage = Float64(totalGrades) / Float64(gradeCount)
        println("全体平均分: ${overallAverage}分")
        println("最高分: ${maxGrade}分")
        println("最低分: ${minGrade}分")
    }
}

// 显示所有学生信息
func displayAllStudents(students: HashMap<String, Student>) {
    println("=== 学生成绩总览 ===")
    
    if (students.size == 0) {
        println("系统中没有学生数据")
        return
    }
    
    for ((studentId, student) in students) {
        println("\n学号: ${studentId}")
        println("姓名: ${student.name}")
        println("班级: ${student.className}")
        print("成绩: ")
        for ((subject, grade) in student.grades) {
            print("${subject}(${grade}) ")
        }
        println("")
        println("平均分: ${student.getAverage()}分")
        println("---")
    }
}

// 查找优秀学生
func findExcellentStudents(students: HashMap<String, Student>, threshold: Float64) {
    println("=== 优秀学生 (平均分 >= ${threshold}) ===")
    var excellentStudents = ArrayList<String>()
    
    for ((_, student) in students) {
        if (student.getAverage() >= threshold) {
            excellentStudents.add(student.name)
        }
    }
    
    if (excellentStudents.size == 0) {
        println("暂无达到标准的优秀学生")
    } else {
        for (name in excellentStudents) {
            println("优秀学生: ${name}")
        }
    }
    println("")
}

// 按科目查找学生成绩
func findStudentsBySubject(students: HashMap<String, Student>, subject: String) {
    println("=== ${subject} 科目成绩 ===")
    var hasSubject = false
    
    for ((_, student) in students) {
        for ((sub, grade) in student.grades) {
            if (sub == subject) {
                println("${student.name}: ${grade}分")
                hasSubject = true
            }
        }
    }
    
    if (!hasSubject) {
        println("没有学生有 ${subject} 成绩记录")
    }
    println("")
}

示例3 基于接口与多态的支付系统

interface Payment + Alipay/WeChatPay/BankCardPay 实现类,PaymentManager 统一管理多种支付方式。

package demo
import std.collection.*

// 定义支付接口
interface Payment {
    func pay(amount: Float64): Bool
}

// 支付宝实现类
class Alipay <: Payment {
    private var balance: Float64

    public init(balance: Float64) {
        this.balance = balance
    }

    public override func pay(amount: Float64): Bool {
        if (amount > balance) {
            println("支付宝支付失败:余额不足")
            return false
        }
        balance -= amount
        println("支付宝支付成功:支付 ${amount} 元,剩余 ${balance} 元")
        return true
    }
}

// 微信支付实现类
class WeChatPay <: Payment {
    private var balance: Float64

    public init(balance: Float64) {
        this.balance = balance
    }

    public override func pay(amount: Float64): Bool {
        if (amount > balance) {
            println("微信支付失败:余额不足")
            return false
        }
        balance -= amount
        println("微信支付成功:支付 ${amount} 元,剩余 ${balance} 元")
        return true
    }
}

// 银行卡支付实现类
class BankCardPay <: Payment {
    private var cardNumber: String
    private var balance: Float64

    public init(cardNumber: String, balance: Float64) {
        this.cardNumber = cardNumber
        this.balance = balance
    }

    public override func pay(amount: Float64): Bool {
        if (cardNumber.size != 16) {
            println("银行卡支付失败:卡号无效")
            return false
        }
        if (amount > balance) {
            println("银行卡支付失败:余额不足")
            return false
        }
        balance -= amount
        println("银行卡支付成功:支付 ${amount} 元,剩余 ${balance} 元")
        return true
    }
}

// 支付管理器
class PaymentManager {
    private let methods: ArrayList<Payment>  

    public init() {
        this.methods = ArrayList<Payment>()   
    }

    public func addMethod(method: Payment) {
        methods.add(method)
    }

    public func processPayments(amount: Float64) {
        for (method in methods) {
            method.pay(amount)
        }
    }
}

main() {
    println("=== 仓颉语言支付系统演示 ===\n")

    let manager = PaymentManager()
    manager.addMethod(Alipay(100.0))
    manager.addMethod(WeChatPay(50.0))
    manager.addMethod(BankCardPay("1234567890123456", 200.0))
    manager.addMethod(BankCardPay("9999", 500.0))  // 错误卡号

    manager.processPayments(60.0)

    return 0
}

示例4 单词去重与统计

使用 HashSet 去重,输出去重后的单词集合并判断某个单词是否存在。

package demo
import std.collection.*

main() {
    let words = ["apple", "banana", "apple", "orange", "banana", "pear"]
    let uniqueWords = HashSet<String>(words)

    println("去重后的单词集合: ${uniqueWords}")
    println("是否包含 apple: ${uniqueWords.contains("apple")}")
    println("是否包含 grape: ${uniqueWords.contains("grape")}")
}

示例5 简易汉字结构字典的创建及查询

利用 HashMap 与 ArrayList 组合创建汉字结构字典,支持添加部件和查询汉字结构。

package demo
import std.collection.ArrayList
import std.collection.HashMap
// 自定义简易汉字结构字典类
class HanziDictionary {
    var dict: HashMap<String, ArrayList<String>>
    init() {
        dict = HashMap<String, ArrayList<String>>()
    }

    // 添加汉字和部件
    func addCharacter(ch: String, parts: ArrayList<String>) {
        dict.add(ch, parts)
    }

    // 查询某个汉字的结构部件
    func query(ch: String) {
        if (dict.contains(ch)) {
            let parts = dict.get(ch)
            print("汉字 '${ch}' 的部件是:")
            println(parts)
        } else {
            println("字典中没有 '${ch}' 这个汉字")
        }
    }

    // 打印整个字典
    func printDict() {
        println(dict)
    }
}

main() {
    let hzDict = HanziDictionary()
    let partsMing = ArrayList<String>()
    partsMing.add("日")
    partsMing.add("月")
    hzDict.addCharacter("明", partsMing)
    let partsLin = ArrayList<String>()
    partsLin.add("木")
    partsLin.add("木")
    hzDict.addCharacter("林", partsLin)
    let partsHao = ArrayList<String>()
    partsHao.add("女")
    partsHao.add("子")
    hzDict.addCharacter("好", partsHao)
    // 打印整个字典
    hzDict.printDict()
    // 查询特定汉字结构
    hzDict.query("明")
    // 查询不存在的汉字
    hzDict.query("电")
}