Scala 中不同类型(Integer、Int 和 String)的比较操作,涉及 ==、equals 和 eq 三种比较方式

解释下面代码的运行结果

Scala 复制代码
package sparksessiondemo

object adress {
  def main(args: Array[String]): Unit = {
    val a:Integer = 10
    val b:Integer = 10

    println(a == b)    //true
    println(a.equals(b))  //true
    println(a.eq(b))   //true


    val a1: Integer = 128
    val b1: Integer = 128

    println(a1 == b1) //true
    println(a1.equals(b1)) //true
    println(a1.eq(b1)) //false


    val c: Int = 10
    val d: Int = 10

    println(c == d) //true
    println(c.equals(d)) //true
    //println(c.eq(d)) //the result type of an implicit conversion must be more specific than AnyRef


    val c1: Int = 128
    val d1: Int = 128

    println(c1 == d1) //true
    println(c1.equals(d1)) //true
   // println(c1.eq(d1)) //the result type of an implicit conversion must be more specific than AnyRef


    val e: String = "128"
    val f: String = "128"

    println(e == f) //true
    println(e.equals(f)) //true
    println(e.eq(f))  //true


    val e1: String = new String("128")
    val f1: String = new String("128")

    println(e1 == f1) //true
    println(e1.equals(f1)) //true
    println(e1.eq(f1))  //false

  }
}

这段代码展示了 Scala 中不同类型(Integer、Int 和 String)的比较操作,涉及 ==、equals 和 eq 三种比较方式。以下是对代码结果的详细解释:


1. Integer 类型的比较

Integer 是 Java 中的包装类,Scala 继承了 Java 的行为。

第一部分:a 和 b 的比较
Scala 复制代码
val a: Integer = 10
val b: Integer = 10

println(a == b)    // true
println(a.equals(b))  // true
println(a.eq(b))   // true
  • a == b:

    • == 是值比较,10 == 10,结果为 true。
  • a.equals(b):

    • equals 是值比较,10.equals(10),结果为 true。
  • a.eq(b):

    • eq 是引用比较。由于 10 在 -128 到 127 范围内,a 和 b 指向缓存中的同一个对象,结果为 true。
第二部分:a1 和 b1 的比较
Scala 复制代码
val a1: Integer = 128
val b1: Integer = 128

println(a1 == b1) // true
println(a1.equals(b1)) // true
println(a1.eq(b1)) // false
  • a1 == b1:

    • 值比较,128 == 128,结果为 true。
  • a1.equals(b1):

    • 值比较,128.equals(128),结果为 true。
  • a1.eq(b1):

    • 引用比较。由于 128 超出了 -128 到 127 的范围,a1 和 b1 是两个不同的对象,结果为 false。

2. Int 类型的比较

Int 是 Scala 中的基本类型(值类型),不是引用类型。

第一部分:c 和 d 的比较
Scala 复制代码
val c: Int = 10
val d: Int = 10

println(c == d) // true
println(c.equals(d)) // true
// println(c.eq(d)) // 编译错误
  • c == d:

    • 值比较,10 == 10,结果为 true。
  • c.equals(d):

    • 值比较,10.equals(10),结果为 true。
  • c.eq(d):

    • eq 是引用比较,但 Int 是值类型,没有引用。Scala 会尝试将 Int 隐式转换为 AnyRef,但无法确定具体类型,因此编译错误。
第二部分:c1 和 d1 的比较
Scala 复制代码
val c1: Int = 128
val d1: Int = 128

println(c1 == d1) // true
println(c1.equals(d1)) // true
// println(c1.eq(d1)) // 编译错误
  • c1 == d1:

    • 值比较,128 == 128,结果为 true。
  • c1.equals(d1):

    • 值比较,128.equals(128),结果为 true。
  • c1.eq(d1):

    • 同上,Int 是值类型,无法进行引用比较,编译错误。

3. String 类型的比较

String 是引用类型,Scala 中的 String 行为与 Java 一致。

第一部分:e 和 f 的比较
Scala 复制代码
val e: String = "128"
val f: String = "128"

println(e == f) // true
println(e.equals(f)) // true
println(e.eq(f))  // true
  • e == f:

    • 值比较,"128" == "128",结果为 true。
  • e.equals(f):

    • 值比较,"128".equals("128"),结果为 true。
  • e.eq(f):

    • 引用比较。由于字符串常量池的存在,e 和 f 指向同一个对象,结果为 true。
第二部分:e1 和 f1 的比较
Scala 复制代码
val e1: String = new String("128")
val f1: String = new String("128")

println(e1 == f1) // true
println(e1.equals(f1)) // true
println(e1.eq(f1))  // false
  • e1 == f1:

    • 值比较,"128" == "128",结果为 true。
  • e1.equals(f1):

    • 值比较,"128".equals("128"),结果为 true。
  • e1.eq(f1):

    • 引用比较。由于 new String("128") 创建了新的对象,e1 和 f1 是两个不同的对象,结果为 false。

总结

类型 操作符/方法 比较内容 结果(值 10 或 "128") 结果(值 128 或 new String("128"))
Integer == 值比较 true true
equals 值比较 true true
eq 引用比较 true(缓存) false(新对象)
Int == 值比较 true true
equals 值比较 true true
eq 引用比较 编译错误 编译错误
String == 值比较 true true
equals 值比较 true true
eq 引用比较 true(常量池) false(新对象)

关键点

  1. Integer 的缓存机制:

    • Java 和 Scala 对 Integer 类型有一个缓存机制:对于值在 -128 到 127 之间的 Integer 对象,会从缓存中返回相同的对象,eq 返回 true。

    • 对于超出这个范围的值,每次都会创建新的 Integer 对象,eq 返回 false。

  2. Int 是值类型:

    • Int 没有引用,eq 无法使用。
  3. String 的常量池:

    • 直接赋值的字符串会使用常量池,eq 返回 true。

    • 使用 new String 创建的对象会生成新的引用,eq 返回 false。

    • 关于String常量池的更详细说明,见:Scala 中的String常量池-CSDN博客

通过这些例子,可以清楚地理解 Scala 中不同类型的行为及其比较操作的区别。

相关推荐
杨丰玮4187 小时前
C语言核心语法
java·c语言·开发语言·学习方法
ttwuai7 小时前
Go开源后台管理系统推荐:README、源码和License应该怎么验
开发语言·golang·开源
Java后端的Ai之路7 小时前
Python 进阶探索30 - Python中的装饰器
开发语言·人工智能·python·文件处理·装饰器模式
沫璃染墨7 小时前
《从零入门Linux系统篇(五十八):线程篇·十一——线程安全与死锁详解:从可重入到多锁管理》
linux·服务器·开发语言·c++·驱动开发·安全·架构
2601_967212727 小时前
灵活扩展型电源轨道系统服务商技术路线对比与选型参考
大数据·经验分享
黑妹天下第一乖7 小时前
第 05 讲:阿加犀 AidCV 图像处理加速与 OpenCV 一致开发实战
开发语言·图像处理·人工智能·嵌入式硬件·数码相机·opencv·计算机视觉
言乐67 小时前
Python基于关键词分拣快递(适用于电商与货运代理等)
开发语言·python·django·virtualenv·pygame
一条破秋裤7 小时前
01_字符设备基本概念_从分类到LED控制链路
开发语言·php
朝朝辞暮i7 小时前
C++ 第 40 章:ROS2 Publisher + Timer + Subscriber + Callback + Executor 完整闭环
开发语言·c++·算法·ros2
W***25927 小时前
深度解读Work Agent长程任务执行的底层运行逻辑
大数据·人工智能