目录

Scala-中不同类型IntegerInt-和-String的比较操作,涉及-equals-和-eq-三种比较方式

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

解释下面代码的运行结果

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 中不同类型( IntegerIntString )的比较操作,涉及 ==equalseq 三种比较方式。以下是对代码结果的详细解释:

1. Integer 类型的比较

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

第一部分: ab 的比较
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-128127 范围内, ab 指向缓存中的同一个对象,结果为 true
第二部分: a1b1 的比较
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 超出了 -128127 的范围, a1b1 是两个不同的对象,结果为 false

2. Int 类型的比较

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

第一部分: cd 的比较
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 ,但无法确定具体类型,因此编译错误。
第二部分: c1d1 的比较
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 一致。

第一部分: ef 的比较
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)
  • 引用比较。由于字符串常量池的存在, ef 指向同一个对象,结果为 true
第二部分: e1f1 的比较
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") 创建了新的对象, e1f1 是两个不同的对象,结果为 false

总结

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

关键点

  1. Integer 的缓存机制:
  • Java 和 Scala 对 Integer 类型有一个缓存机制:对于值在 -128127 之间的 Integer 对象,会从缓存中返回相同的对象, eq 返回 true
  • 对于超出这个范围的值,每次都会创建新的 Integer 对象, eq 返回 false
  1. Int 是值类型:
  • Int 没有引用, eq 无法使用。
  1. String 的常量池:
  • 直接赋值的字符串会使用常量池, eq 返回 true
  • 使用 new String 创建的对象会生成新的引用, eq 返回 false。
  • 关于String常量池的更详细说明,见: 通过这些例子,可以清楚地理解 Scala 中不同类型的行为及其比较操作的区别。