一、问题引入:自定义类存入 Set 为何无法去重?
先看一个基础案例:定义一个Book类,创建两个 “内容相同” 的Book对象,存入可变 Set 中,观察结果:
package caseclass1
// 导入mutable包下的Set(也可使用通配符import scala.collection.mutable._)
import scala.collection.mutable.Set
object CaseClass {
class Book(var id: Int, var name: String) {
override def equals(obj: Any): Boolean = obj match {
case other: Book => other.id == this.id && other.name == this.name
case _ => false // 非Book类型直接返回false
}
override def hashCode(): Int = id.hashCode() + name.hashCode()
}
def main(args: Array[String]): Unit = {
val set1 = Set(1, 2)
set1 += 1
set1 += 1
set1 += 1
set1 += 1
println("set1内容:" + set1)
val book1 = new Book(1, "西游记")
val book2 = new Book(1, "西游记")
println("book1 == book2?" + (book1 == book2))
// 类型修正:book → Book(类名首字母大写)
val set2: Set[Book] = Set()
set2 += book1
set2 += book2
println("set2大小:" + set2.size)
}
}
二、手动实现 equals 和 hashCode 解决去重
要让 Set 根据Book的内容去重,需手动重写equals和hashCode方法:
package caseclass1
// 导入mutable包下的Set(也可使用通配符import scala.collection.mutable._)
import scala.collection.mutable.Set
object caseClass {
class Book(var id: Int, var name: String) {
}
def main(args: Array[String]): Unit = {
val book1 = new Book(1, "西游记")
val book2 = new Book(1, "西游记")
println("book1 == book2?" + (book1 == book2))
// 类型修正:book → Book(类名首字母大写)
val set2: Set[Book] = Set()
set2 += book1
set2 += book2
println("set2大小:" + set2.size)
}
}
三、Scala 样例类(Case Class):自动实现相等性判断
手动重写equals和hashCode虽能解决问题,但代码冗余。Scala 提供样例类(Case Class) ,自动为我们实现这些方法,还附带其他便捷特性:
package caseclass1
/* case class 样板类
可以省略 new
属性默认不可变的 val修饰
它会自动去实现toString equlas hascode等方法
*/
object caseclass3 {
case class Student (name:String, age:Int)
def main(args: Array[String]): Unit = {
//val st1 = new Student("小花" 18)
//可以省略 new
val st1 = Student("小花" ,18)
val st2 = Student("小花" ,18)
println(st1)
println(st1 == st2)
}
}