它是什么意思"在Scala ==和!=方法中检查值是否相等而不是Java,它们检查参考相等性"

时间:2017-03-17 18:30:17

标签: java scala

我正在学习scala并重温基础知识。

我无法理解它的含义"在Scala中==和!=方法检查值是否相等而不是Java,它们检查参考相等性"。

有人可以举一些例子并尝试用简单的英语解释吗?

1 个答案:

答案 0 :(得分:2)

案例1 - value classesAnyVal)和case classes

使用scala中的值类,==!=进行值检查。

  

值类是其实例未表示为的类   底层主机系统的对象。所有值类都继承自   AnyVal类。

scala IntFloat等中的所有原语都是值类。

scala> val quantity1 = 100
quantity1: Int = 100

scala> val quantity2 = 100
quantity2: Int = 100

scala> quantity1 == quantity2
res9: Boolean = true

此外,对于case classes==隐式工作。

  

案例类应该是普通的和不可变的数据保持对象   完全取决于他们的构造函数参数

scala> case class Item(name: String, quantity: Int)
defined class Item

现在,只需按==比较两项,就会检查项目中的所有值是否相等。

scala> Item("Jacket", 100) == Item("Pants", 10)
res0: Boolean = false

scala> Item("Jacket", 100) == Item("Jacket", 100)
res1: Boolean = true

案例2 - scala(AnyRef)和java类(java.lang.Object)中的ref类

但是对于scala和所有Java类中的Ref类,如果执行==,它会检查实例引用而不是值,直到您编写自己的equals method

Java示例,

static class Item {
        String name;
        int quantity;

        Item(String name, int quantity){
            this.name = name;
            this.quantity = quantity;
        }
    }
    public static void main(String[] args) {
        Item item1 = new Item("Jacket", 100);
        Item item2 = new Item("Pants", 10);
        Item item3 = new Item("Jacket", 100);

        System.out.println(item1 +"==" + item2 + " " + (item1 == item2)); //false
        System.out.println(item1 +"==" + item3 + " " + (item1 == item3)); //false
    }

==比较结果将是

com.somepackage.EqualityTests$Item@1b28cdfa==com.somepackage.EqualityTests$Item@eed1f14 false
com.somepackage.EqualityTests$Item@1b28cdfa==com.somepackage.EqualityTests$Item@7229724f false

其中1b28cdfaitem1的实例参考。您看到item1item3具有相同的数据,但==给出了错误,因为它们是指向两个不同地址的两个不同实例。

要模仿scala对值类==执行的操作,请按照以下方法实施equals方法并执行手动相等检查。

static class Item {
    String name;
    int quantity;

    Item(String name, int quantity){
        this.name = name;
        this.quantity = quantity;
    }

    @Override
    public boolean equals(Object obj) {
        Item i = (Item) obj;
        return this.name.equals(((Item) obj).name) && this.quantity == ((Item) obj).quantity;
    }
}

public static void main(String[] args) {
    Item item1 = new Item("Jacket", 100);
    Item item2 = new Item("Pants", 10);
    Item item3 = new Item("Jacket", 100);

    System.out.println(item1 +".equals(" + item3 + ") " + (item1.equals(item3))); //true
}

与scala Ref类相同,`==`如果未实现equals方法则比较引用

scala> class Store(name: String){} //equivalent to Store extends `AnyRef`
defined class Store

scala> val store1 = new Store("a")
store1: Store = Store@2063c53e

scala> val store2 = new Store("a")
store2: Store = Store@61c76850

scala> store1 == store2
res7: Boolean = false

但是,如果scala Ref类中有您自己的equals方法,则==引用您的.equals方法。

示例,

scala> :paste
// Entering paste mode (ctrl-D to finish)

class Store(val name: String){
    override def equals(that: Any) : Boolean = {
         val thatStore = that.asInstanceOf[Store]
         name == thatStore.name
    }
}

scala> new Store("JWN") == new Store("JWN") // calls s1.equals(s2)
res1: Boolean = true