SlideShare a Scribd company logo
Object Equality In Scala


         Ruchi Agarwal
       Software Consultant
            Knoldus
Object Equality In Java & Scala:

- Two equality comparisons:
    1. == Operator
    2. Equals()

- The == operator, which is the natural equality for value types and object indentity for
   Refernce types in Java.

// This is Java
boolean isEqual(int x, int y){

    return x == y;                         // Natural equality on value types

}
System.out.println(isEqual ( 421, 421));       //Output: True

//java.lang.Integer(Object)

boolean isEqual(Integer x, Integer y){

    return x == y;                         // Reference equality on reference types
}
System.out.println(isEqual ( 421, 421));       //Output: False
- The == equality is reserved in Scala for the “ Natural ” equality of each type. The
  equality operation == in scala is designed to be transparent with respect to the type's
  representation.

- For value types, it is the natural (numeric or boolean) equality.

- For reference types, == is treated as an alias of the equals() inherited from object.

//This is Scala

scala> def isEqual(x : Int , y : Int) = x == y
isEqual: (x: Int, y: Int )Boolean

scala> isEqual( 421 , 421)
res8: Boolean = true

scala> def isEqual(x : Any , y : Any) = x == y
isEqual: (x: Any , y: Any)Boolean

scala> isEqual( 421 , 421)
res8: Boolean = true
String Comparisons:
- Scala, never fall into Java's well-known trap concerning string comparisons.

//This is Scala

scala> val x=“abcd”.substring(2)
x: java.lang.String = cd

scala> val y=“abcd”.substring(2)
y: java.lang.String = cd

scala> x == y
res7: Boolean = true

//This is Java
boolean isEquals(String x, String y){

    return x.substring(2) == y.substring(2);     //return x.substring(2).equals(y.substring(2));
                                                 //Output: true
}
String s1="abcd";
String s2="abcd";
System.out.println(isEquals(s1, s2));            //Output: false
Reference Equality:

- For refernce equality, Scala's class AnyRef defines an additional eq method, which
  cannot be overridden and is implemented as reference equality(i. e., it behaves like ==
  in Java for reference types).

scala> val x=new String(“abc”)
x: java.lang.String = abc

scala> val x=new String("abc")
x: java.lang.String = abc

scala> x == y
res13: Boolean = true                                     // Value equality

scala> x eq y
res14: Boolean = false                                    // Reference Equality

- There's also the negation of eq , which is called ne.

 scala> x ne y
res14: Boolean = true
- For refernce equality, the behavior of == for new types can redefine by overriding the
  equals method, which is always inherited from class Any.

- It is not possible to override == directly, as it is defined as a final method in class Any.

// defination of == in Any class

final def == (that : Any) : Boolean =
     if ( null eq this) { null eq that }
           else { this equals that }
Writing an Equality Method:

 - Writing a correct equality method is surprisingly difficult in object-oriented languages.

 - This is problematic, because equality is at the basis of many other things.

 - Here are four common pitfalls that can cause inconsistent behavior when overriding
   equals:

     1. Defining equals with wrong signature

     2. Changing equals without also changing hashCode

     3. Defining equals in terms of mutable fields

     4. Failing to define equals as an equivalence relation
Pitfall #1: Defining equals with wrong signature
class Point ( val x:Int, val y :Int)    {

     def equals (other: Point): Boolean =          //Overloaded equals()
        this.x == other.x && this.y == other.y
 }

scala> val p1, p2 = new Point (1 , 2)
p1: Point = Point@1e0bb90
p2: Point = Point@139fb49

scala> val q= new Point( 2 , 3)
q: Point = Point@a44ec3

//Working OK
scala> p1 equals p2                    res:0 Boolean : true
scala> p1 equals q                     res:0 Boolean : false

//Trouble

scala> val p2a: Any = p2               // Alias of p2
p2a: Any = Point@139fb49

// p2a calling equals() of Any class
scala> p1 equals p2a                   res:0 Boolean : false
Solution: Correct Signature


 class Point ( val x:Int, val y :Int)         {

     //        A better definition:Overriding equals of Any class

      override def equals(other: Any) = other match {

              case that: Point => this.x == that.x && this.y == that.y

              case _ => false

          }
 }


 scala> val p2a: Any = p2                   // Alias of p2
 p2a: Any = Point@139fb49

 scala> p1 equals p2a                       res:0 Boolean : true
- A related pitfall is to define == with a wrong signature.

- If try to redefine == with the correct signature, which takes an argument of type Any, the
  compiler will give an error because you try to override a final method of type Any.

- However, newcomers to Scala sometimes make two errors at once: They try to override ==
  and they give it the wrong signature.

- For instance:

         def ==(other: Point): Boolean = // Don’t do this! (User-defined == method)

- In that case, the user-defined == method is treated as an overloaded variant of the
  same-named method class Any, and the program compiles.

- However, the behavior of the program would be just as dubious as if you had defined
  equals with the wrong signature.
Pitfall #2: Changing equals without also changing hashCode
  //Previously defined equals method

  class Point ( val x:Int, val y :Int)        {

      //        A better definition:Overriding equals of Any class

       override def equals(other: Any) = other match {

               case that: Point => this.x == that.x && this.y == that.y

               case _ => false
           }
  }

  scala> import scala.collection.mutable._
  import scala.collection.mutable._

  scala> val p1, p2 = new Point (1 , 2)
  p1: Point = Point@1bef480
  p2: Point = Point@1a6068c

  //storing p1 to collection
  scala> val coll = HashSet (p1)
  coll: scala.collection.mutable.Set[Point] = Set(Point@62d74e)

  scala> coll contains p2                         res2: Boolean = false
- In fact, this outcome is not 100% certain. We might also get true from the experiment.
  We can try with some other points with coordinates 1 and 2. Eventually, we’ll get one
  which is not contained in the set.



                                hashSet(p1) contains p2


                 val p2
    true         val p1                                            val p2
                                         false
                  hashSet                                       Hash Bucket
               Hash Bucket
                    Pitfall #2: Changing equals without also changing hashCode
- Wrong here is that Point redefined equals without also redefining hashCode.

- The problem was that the last implementation of Point violated the contract on hashCode as
   defined for class Any:

   If two objects are equal according to the equals method, then calling the
  hashCode method on each of the two objects must produce the same integer result.

- In fact, it’s well known in Java that hashCode and equals should always be redefined
   together.

- Furthermore, hashCode may only depend on fields that equals depends on.

- For the Point class, the following would be a suitable definition of hashCode:


      override def hashCode = 41 * (41 + x) + y                   // Redefine hashCode


- This is just one of many possible implementations of hashCode.

- Adding hashCode fixes the problems of equality when defining classes like Point.
class Point(val x: Int, val y: Int) {

    override def hashCode = 41 * (41 + x) + y               // Redefine hashCode

    override def equals(other: Any) = other match {         // Redefine equals()

        case that: Point => this.x == that.x && this.y == that.y
        case _ => false

    }

}

scala> val p1, p2 = new Point(1, 2)
p1: Point = Point@6bc
p2: Point = Point@6bc

scala> coll contains p2                  res2: Boolean = true
Pitfall #3: Defining equals in terms of mutable fields:
  - Consider the following slight variation of class Point:
    class Point2(var x: Int, var y: Int) {

         override def hashCode = 41 * (41 + x) + y                       // Redefine hashCode

         override def equals(other: Any) = other match { // Redefine equals()

              case that: Point2 => this.x == that.x && this.y == that.y
              case _ => false
         }
    }

    scala> val p = new Point(1, 2)                              p: Point = Point@2b

    scala> val coll = HashSet(p)
    coll: scala.collection.mutable.Set[Point] = Set(Point@2b)

    scala> coll contains p                                      res5: Boolean = true

    scala> p.x += 1                              // Changing p.x value

    scala> coll contains p                                      res7: Boolean = false

    scala> coll.elements contains p                             res7: Boolean = true
coll.elements contains p
                true


                                        p.x += 1
                                                                               After change value it
                                        (x:mutable)                            assign to wrong hash
                                                                                      bucket
             p.x=1                                               p.x=2
                                          coll contains p
             coll                               false         Hash Bucket
          Hash Bucket

                      Pitfall #3: Defining equals in terms of mutable fields


- In a manner of speaking, the point p “dropped out of sight” in the set coll even though it
  still belonged to its elements.

- If you need a comparison that takes the current state of an object into account, you
  should usually name it something else, not equals.
Pitfall #4: Failing to define equals as an equivalence relation:
   - In scala, Any class specifies that equals must implement an equivalence relation on
   non-null objects:

       • It is reflexive: for any non-null value x , the expression x.equals(x) should return true.

       • It is symmetric: for any non-null values x and y, x.equals(y) should return true if and
                         only if y.equals(x) returns true.

       • It is transitive: for any non-null values x, y, and z, if x.equals(y) returns true and
                         y.equals(z) returns true, then x.equals(z) should return true.

       • It is consistent: for any non-null values x and y, multiple invocations of x.equals(y)
                           should consistently return true or consistently return false, provided
         no information used in equals comparisons on the objects is modified.

       • For any non-null value x, x.equals(null) should return false.

   - The definition of equals developed so far for class Point satisfies the contract for equals.

   - However, things become more complicated once subclasses are considered.
Symmetric Problem:
  class Point(val x: Int, val y: Int) {

      override    def hashCode = 41 * (41 + x) + y    // Redefine hashCode
      override    def equals(other: Any) = other match { // Redefine equals()
          case    that: Point => this.x == that.x && this.y == that.y
          case    _ => false
      }
  }

  object Color extends Enumeration {
      val Red, Orange, Yellow, Green, Blue, Indigo, Violet = Value
  }

  class ColoredPoint(x: Int, y: Int, val color: Color.Value)
         extends Point(x, y) {         // Problem: equals not symmetric

           override def equals(other: Any) = other match {
               case that: ColoredPoint =>this.color == that.color &&
                                         super.equals(that)
               case _ => false
           }
       }
  scala> val p = new Point(1, 2)                      p: Point = Point@2b
  scala> val cp = new ColoredPoint(1, 2, Color.Red)   cp: ColoredPoint =ColoredPoint@2b
  scala> p equals cp                                  res:0 Boolean : true
  scala> cp equals p                                  res:0 Boolean : false
Solution of Symmetric Problem but violated Transitivity contract:

  class Point(val x: Int, val y: Int) {

      override   def hashCode = 41 * (41 + x) + y    // Redefine hashCode
      override   def equals(other: Any) = other match { // Redefine equals()
          case   that: Point => this.x == that.x && this.y == that.y
          case   _ => false
      }
  }

  object Color extends Enumeration {
      val Red, Orange, Yellow, Green, Blue, Indigo, Violet = Value
  }

  class ColoredPoint(x: Int, y: Int, val color: Color.Value)
         extends Point(x, y) {         // Problem: equals not transitive

          override def equals(other: Any) = other match {
              case that: ColoredPoint =>this.color == that.color &&
                                    super.equals(that)
              case that:Point=>that equals this //new case to make symmetric
              case _ => false
          }
      }
  scala> p equals cp                            res:0 Boolean : true
  scala> cp equals p                            res:0 Boolean : true
- Here’s a sequence of statements that demonstrates transitive. Define a point and two
  colored points of different colors, all at the same position:
        scala> var redp=new ColoredPoint(1,2,Color.Red)
        redp: ColoredPoint = ColoredPoint@6bc

        scala> var bluep=new ColoredPoint(1,2,Color.Blue)
        bluep: ColoredPoint = ColoredPoint@6bc

        scala> var p=new Point(1,2)
        p: Point = Point@6bc

        scala> redp == p                                     res1: Boolean = true
        scala> p == bluep                                    res1: Boolean = true
        scala> redp == bluep                                 res1: Boolean = false


- Hence, the transitivity clause of equals’s contract is violated.

- One way to make equals stricter is to always treat objects of different classes as different.

- That could be achieved by modifying the equals methods in classes Point and
  ColoredPoint.

- In class Point, you could add an extra comparison that checks whether the run-time class
  of the other Point is exactly the same as this Point’s class, as follows:
Solution of Transitivity Problem:
class Point(val x: Int, val y: Int) {

    override def hashCode = 41 * (41 + x) + y           // Redefine hashCode
    override def equals(that: Any) = other match {      // Redefine equals()

         case that: Point => this.x == that.x && this.y == that.y
                           && this.getClass == that.getClass
         case _ => false
         }
}
    object Color extends Enumeration {
        val Red, Orange, Yellow, Green, Blue, Indigo, Violet = Value
    }

class ColoredPoint(x: Int, y: Int, val color: Color.Value)
               extends Point(x, y) {

    override def equals(that: Any) = other match {
        case that: ColoredPoint =>(this.color == that.color)&& super.equals(that)
        case _ => false
    }
}
scala> redp == p                          res:0 Boolean : false
scala> p == bluep                         res:0 Boolean : false
scala> redp == bluep                      res:0 Boolean : false
- Here, an instance of class Point is considered to be equal to some other instance of the
  same class only if the objects have the same coordinates and they have the same run-
time class.

- Meaning .getClass on either object returns the same value.

- The new definitions satisfy symmetry and transitivity because now every comparison
  between objects of different classes yields false.

- So a colored point can never be equal to a point.
Object Equality in Scala

More Related Content

What's hot

Why functional programming and category theory strongly matters
Why functional programming and category theory strongly mattersWhy functional programming and category theory strongly matters
Why functional programming and category theory strongly matters
Piotr Paradziński
 
Hashing algorithms and its uses
Hashing algorithms and its usesHashing algorithms and its uses
Hashing algorithms and its uses
Jawad Khan
 
Python dictionary
Python dictionaryPython dictionary
Python dictionary
Sagar Kumar
 
Java: Regular Expression
Java: Regular ExpressionJava: Regular Expression
Java: Regular ExpressionMasudul Haque
 
Inheritance
InheritanceInheritance
Inheritance
Siddhesh Palkar
 
Function overloading
Function overloadingFunction overloading
Function overloading
Prof. Dr. K. Adisesha
 
Regular Expressions 101
Regular Expressions 101Regular Expressions 101
Regular Expressions 101Raj Rajandran
 
Back patching
Back patchingBack patching
Back patching
santhiya thavanthi
 
Running Free with the Monads
Running Free with the MonadsRunning Free with the Monads
Running Free with the Monads
kenbot
 
Inheritance in C++
Inheritance in C++Inheritance in C++
Inheritance in C++
Laxman Puri
 
Hash tables
Hash tablesHash tables
Hash tables
Rajendran
 
Counting Sort and Radix Sort Algorithms
Counting Sort and Radix Sort AlgorithmsCounting Sort and Radix Sort Algorithms
Counting Sort and Radix Sort Algorithms
Sarvesh Rawat
 
Java Collections Framework
Java Collections FrameworkJava Collections Framework
Java Collections Framework
Sony India Software Center
 
ADO.NET
ADO.NETADO.NET
ADO.NET
Wani Zahoor
 
ITFT-Constants, variables and data types in java
ITFT-Constants, variables and data types in javaITFT-Constants, variables and data types in java
ITFT-Constants, variables and data types in java
Atul Sehdev
 
Domain Modeling in a Functional World
Domain Modeling in a Functional WorldDomain Modeling in a Functional World
Domain Modeling in a Functional World
Debasish Ghosh
 
Introduzione ad ECMAScript 6 (ES6) e TypeScript
Introduzione ad ECMAScript 6 (ES6) e TypeScriptIntroduzione ad ECMAScript 6 (ES6) e TypeScript
Introduzione ad ECMAScript 6 (ES6) e TypeScript
Giovanni Buffa
 
Regular Expressions Cheat Sheet
Regular Expressions Cheat SheetRegular Expressions Cheat Sheet
Regular Expressions Cheat Sheet
Akash Bisariya
 
Namespaces
NamespacesNamespaces
Namespaces
Sangeetha S
 

What's hot (20)

Why functional programming and category theory strongly matters
Why functional programming and category theory strongly mattersWhy functional programming and category theory strongly matters
Why functional programming and category theory strongly matters
 
Hashing algorithms and its uses
Hashing algorithms and its usesHashing algorithms and its uses
Hashing algorithms and its uses
 
Python dictionary
Python dictionaryPython dictionary
Python dictionary
 
Java: Regular Expression
Java: Regular ExpressionJava: Regular Expression
Java: Regular Expression
 
Inheritance
InheritanceInheritance
Inheritance
 
Function overloading
Function overloadingFunction overloading
Function overloading
 
Regular Expressions 101
Regular Expressions 101Regular Expressions 101
Regular Expressions 101
 
Back patching
Back patchingBack patching
Back patching
 
Running Free with the Monads
Running Free with the MonadsRunning Free with the Monads
Running Free with the Monads
 
Inheritance in C++
Inheritance in C++Inheritance in C++
Inheritance in C++
 
Hash tables
Hash tablesHash tables
Hash tables
 
Grammar
GrammarGrammar
Grammar
 
Counting Sort and Radix Sort Algorithms
Counting Sort and Radix Sort AlgorithmsCounting Sort and Radix Sort Algorithms
Counting Sort and Radix Sort Algorithms
 
Java Collections Framework
Java Collections FrameworkJava Collections Framework
Java Collections Framework
 
ADO.NET
ADO.NETADO.NET
ADO.NET
 
ITFT-Constants, variables and data types in java
ITFT-Constants, variables and data types in javaITFT-Constants, variables and data types in java
ITFT-Constants, variables and data types in java
 
Domain Modeling in a Functional World
Domain Modeling in a Functional WorldDomain Modeling in a Functional World
Domain Modeling in a Functional World
 
Introduzione ad ECMAScript 6 (ES6) e TypeScript
Introduzione ad ECMAScript 6 (ES6) e TypeScriptIntroduzione ad ECMAScript 6 (ES6) e TypeScript
Introduzione ad ECMAScript 6 (ES6) e TypeScript
 
Regular Expressions Cheat Sheet
Regular Expressions Cheat SheetRegular Expressions Cheat Sheet
Regular Expressions Cheat Sheet
 
Namespaces
NamespacesNamespaces
Namespaces
 

Similar to Object Equality in Scala

RubyMiniGuide-v1.0_0
RubyMiniGuide-v1.0_0RubyMiniGuide-v1.0_0
RubyMiniGuide-v1.0_0tutorialsruby
 
RubyMiniGuide-v1.0_0
RubyMiniGuide-v1.0_0RubyMiniGuide-v1.0_0
RubyMiniGuide-v1.0_0tutorialsruby
 
Lecture 5: Functional Programming
Lecture 5: Functional ProgrammingLecture 5: Functional Programming
Lecture 5: Functional ProgrammingEelco Visser
 
Real World Haskell: Lecture 4
Real World Haskell: Lecture 4Real World Haskell: Lecture 4
Real World Haskell: Lecture 4Bryan O'Sullivan
 
An introduction to javascript
An introduction to javascriptAn introduction to javascript
An introduction to javascript
MD Sayem Ahmed
 
The JavaScript Programming Language
The JavaScript Programming LanguageThe JavaScript Programming Language
The JavaScript Programming Language
Mohammed Irfan Shaikh
 
Equality For All!
Equality For All!Equality For All!
Equality For All!
bvenners
 
javaimplementation
javaimplementationjavaimplementation
javaimplementationFaRaz Ahmad
 
ScalaLanguage_ch_4_5.pptx
ScalaLanguage_ch_4_5.pptxScalaLanguage_ch_4_5.pptx
ScalaLanguage_ch_4_5.pptx
jkapardhi
 
Wrong
WrongWrong
Effective Java - Methods Common to All Objects
Effective Java - Methods Common to All ObjectsEffective Java - Methods Common to All Objects
Effective Java - Methods Common to All Objects
Roshan Deniyage
 
Introducing Assignment invalidates the Substitution Model of Evaluation and v...
Introducing Assignment invalidates the Substitution Model of Evaluation and v...Introducing Assignment invalidates the Substitution Model of Evaluation and v...
Introducing Assignment invalidates the Substitution Model of Evaluation and v...
Philip Schwarz
 
Keeping objects healthy with Object::Exercise.
Keeping objects healthy with Object::Exercise.Keeping objects healthy with Object::Exercise.
Keeping objects healthy with Object::Exercise.
Workhorse Computing
 
Ruby Gotchas
Ruby GotchasRuby Gotchas
Ruby Gotchas
Dave Aronson
 
Principles of functional progrmming in scala
Principles of functional progrmming in scalaPrinciples of functional progrmming in scala
Principles of functional progrmming in scala
ehsoon
 
A limited guide to intermediate and advanced Ruby
A limited guide to intermediate and advanced RubyA limited guide to intermediate and advanced Ruby
A limited guide to intermediate and advanced Ruby
Vysakh Sreenivasan
 

Similar to Object Equality in Scala (20)

Functional object
Functional objectFunctional object
Functional object
 
RubyMiniGuide-v1.0_0
RubyMiniGuide-v1.0_0RubyMiniGuide-v1.0_0
RubyMiniGuide-v1.0_0
 
RubyMiniGuide-v1.0_0
RubyMiniGuide-v1.0_0RubyMiniGuide-v1.0_0
RubyMiniGuide-v1.0_0
 
Lecture 5: Functional Programming
Lecture 5: Functional ProgrammingLecture 5: Functional Programming
Lecture 5: Functional Programming
 
Real World Haskell: Lecture 4
Real World Haskell: Lecture 4Real World Haskell: Lecture 4
Real World Haskell: Lecture 4
 
An introduction to javascript
An introduction to javascriptAn introduction to javascript
An introduction to javascript
 
Scala for curious
Scala for curiousScala for curious
Scala for curious
 
The JavaScript Programming Language
The JavaScript Programming LanguageThe JavaScript Programming Language
The JavaScript Programming Language
 
Equality For All!
Equality For All!Equality For All!
Equality For All!
 
Php & my sql
Php & my sqlPhp & my sql
Php & my sql
 
javaimplementation
javaimplementationjavaimplementation
javaimplementation
 
ScalaLanguage_ch_4_5.pptx
ScalaLanguage_ch_4_5.pptxScalaLanguage_ch_4_5.pptx
ScalaLanguage_ch_4_5.pptx
 
Wrong
WrongWrong
Wrong
 
Effective Java - Methods Common to All Objects
Effective Java - Methods Common to All ObjectsEffective Java - Methods Common to All Objects
Effective Java - Methods Common to All Objects
 
Introducing Assignment invalidates the Substitution Model of Evaluation and v...
Introducing Assignment invalidates the Substitution Model of Evaluation and v...Introducing Assignment invalidates the Substitution Model of Evaluation and v...
Introducing Assignment invalidates the Substitution Model of Evaluation and v...
 
Keeping objects healthy with Object::Exercise.
Keeping objects healthy with Object::Exercise.Keeping objects healthy with Object::Exercise.
Keeping objects healthy with Object::Exercise.
 
Ruby Gotchas
Ruby GotchasRuby Gotchas
Ruby Gotchas
 
Principles of functional progrmming in scala
Principles of functional progrmming in scalaPrinciples of functional progrmming in scala
Principles of functional progrmming in scala
 
Scala
ScalaScala
Scala
 
A limited guide to intermediate and advanced Ruby
A limited guide to intermediate and advanced RubyA limited guide to intermediate and advanced Ruby
A limited guide to intermediate and advanced Ruby
 

More from Knoldus Inc.

Getting Started with Apache Spark (Scala)
Getting Started with Apache Spark (Scala)Getting Started with Apache Spark (Scala)
Getting Started with Apache Spark (Scala)
Knoldus Inc.
 
Secure practices with dot net services.pptx
Secure practices with dot net services.pptxSecure practices with dot net services.pptx
Secure practices with dot net services.pptx
Knoldus Inc.
 
Distributed Cache with dot microservices
Distributed Cache with dot microservicesDistributed Cache with dot microservices
Distributed Cache with dot microservices
Knoldus Inc.
 
Introduction to gRPC Presentation (Java)
Introduction to gRPC Presentation (Java)Introduction to gRPC Presentation (Java)
Introduction to gRPC Presentation (Java)
Knoldus Inc.
 
Using InfluxDB for real-time monitoring in Jmeter
Using InfluxDB for real-time monitoring in JmeterUsing InfluxDB for real-time monitoring in Jmeter
Using InfluxDB for real-time monitoring in Jmeter
Knoldus Inc.
 
Intoduction to KubeVela Presentation (DevOps)
Intoduction to KubeVela Presentation (DevOps)Intoduction to KubeVela Presentation (DevOps)
Intoduction to KubeVela Presentation (DevOps)
Knoldus Inc.
 
Stakeholder Management (Project Management) Presentation
Stakeholder Management (Project Management) PresentationStakeholder Management (Project Management) Presentation
Stakeholder Management (Project Management) Presentation
Knoldus Inc.
 
Introduction To Kaniko (DevOps) Presentation
Introduction To Kaniko (DevOps) PresentationIntroduction To Kaniko (DevOps) Presentation
Introduction To Kaniko (DevOps) Presentation
Knoldus Inc.
 
Efficient Test Environments with Infrastructure as Code (IaC)
Efficient Test Environments with Infrastructure as Code (IaC)Efficient Test Environments with Infrastructure as Code (IaC)
Efficient Test Environments with Infrastructure as Code (IaC)
Knoldus Inc.
 
Exploring Terramate DevOps (Presentation)
Exploring Terramate DevOps (Presentation)Exploring Terramate DevOps (Presentation)
Exploring Terramate DevOps (Presentation)
Knoldus Inc.
 
Clean Code in Test Automation Differentiating Between the Good and the Bad
Clean Code in Test Automation  Differentiating Between the Good and the BadClean Code in Test Automation  Differentiating Between the Good and the Bad
Clean Code in Test Automation Differentiating Between the Good and the Bad
Knoldus Inc.
 
Integrating AI Capabilities in Test Automation
Integrating AI Capabilities in Test AutomationIntegrating AI Capabilities in Test Automation
Integrating AI Capabilities in Test Automation
Knoldus Inc.
 
State Management with NGXS in Angular.pptx
State Management with NGXS in Angular.pptxState Management with NGXS in Angular.pptx
State Management with NGXS in Angular.pptx
Knoldus Inc.
 
Authentication in Svelte using cookies.pptx
Authentication in Svelte using cookies.pptxAuthentication in Svelte using cookies.pptx
Authentication in Svelte using cookies.pptx
Knoldus Inc.
 
OAuth2 Implementation Presentation (Java)
OAuth2 Implementation Presentation (Java)OAuth2 Implementation Presentation (Java)
OAuth2 Implementation Presentation (Java)
Knoldus Inc.
 
Supply chain security with Kubeclarity.pptx
Supply chain security with Kubeclarity.pptxSupply chain security with Kubeclarity.pptx
Supply chain security with Kubeclarity.pptx
Knoldus Inc.
 
Mastering Web Scraping with JSoup Unlocking the Secrets of HTML Parsing
Mastering Web Scraping with JSoup Unlocking the Secrets of HTML ParsingMastering Web Scraping with JSoup Unlocking the Secrets of HTML Parsing
Mastering Web Scraping with JSoup Unlocking the Secrets of HTML Parsing
Knoldus Inc.
 
Akka gRPC Essentials A Hands-On Introduction
Akka gRPC Essentials A Hands-On IntroductionAkka gRPC Essentials A Hands-On Introduction
Akka gRPC Essentials A Hands-On Introduction
Knoldus Inc.
 
Entity Core with Core Microservices.pptx
Entity Core with Core Microservices.pptxEntity Core with Core Microservices.pptx
Entity Core with Core Microservices.pptx
Knoldus Inc.
 
Introduction to Redis and its features.pptx
Introduction to Redis and its features.pptxIntroduction to Redis and its features.pptx
Introduction to Redis and its features.pptx
Knoldus Inc.
 

More from Knoldus Inc. (20)

Getting Started with Apache Spark (Scala)
Getting Started with Apache Spark (Scala)Getting Started with Apache Spark (Scala)
Getting Started with Apache Spark (Scala)
 
Secure practices with dot net services.pptx
Secure practices with dot net services.pptxSecure practices with dot net services.pptx
Secure practices with dot net services.pptx
 
Distributed Cache with dot microservices
Distributed Cache with dot microservicesDistributed Cache with dot microservices
Distributed Cache with dot microservices
 
Introduction to gRPC Presentation (Java)
Introduction to gRPC Presentation (Java)Introduction to gRPC Presentation (Java)
Introduction to gRPC Presentation (Java)
 
Using InfluxDB for real-time monitoring in Jmeter
Using InfluxDB for real-time monitoring in JmeterUsing InfluxDB for real-time monitoring in Jmeter
Using InfluxDB for real-time monitoring in Jmeter
 
Intoduction to KubeVela Presentation (DevOps)
Intoduction to KubeVela Presentation (DevOps)Intoduction to KubeVela Presentation (DevOps)
Intoduction to KubeVela Presentation (DevOps)
 
Stakeholder Management (Project Management) Presentation
Stakeholder Management (Project Management) PresentationStakeholder Management (Project Management) Presentation
Stakeholder Management (Project Management) Presentation
 
Introduction To Kaniko (DevOps) Presentation
Introduction To Kaniko (DevOps) PresentationIntroduction To Kaniko (DevOps) Presentation
Introduction To Kaniko (DevOps) Presentation
 
Efficient Test Environments with Infrastructure as Code (IaC)
Efficient Test Environments with Infrastructure as Code (IaC)Efficient Test Environments with Infrastructure as Code (IaC)
Efficient Test Environments with Infrastructure as Code (IaC)
 
Exploring Terramate DevOps (Presentation)
Exploring Terramate DevOps (Presentation)Exploring Terramate DevOps (Presentation)
Exploring Terramate DevOps (Presentation)
 
Clean Code in Test Automation Differentiating Between the Good and the Bad
Clean Code in Test Automation  Differentiating Between the Good and the BadClean Code in Test Automation  Differentiating Between the Good and the Bad
Clean Code in Test Automation Differentiating Between the Good and the Bad
 
Integrating AI Capabilities in Test Automation
Integrating AI Capabilities in Test AutomationIntegrating AI Capabilities in Test Automation
Integrating AI Capabilities in Test Automation
 
State Management with NGXS in Angular.pptx
State Management with NGXS in Angular.pptxState Management with NGXS in Angular.pptx
State Management with NGXS in Angular.pptx
 
Authentication in Svelte using cookies.pptx
Authentication in Svelte using cookies.pptxAuthentication in Svelte using cookies.pptx
Authentication in Svelte using cookies.pptx
 
OAuth2 Implementation Presentation (Java)
OAuth2 Implementation Presentation (Java)OAuth2 Implementation Presentation (Java)
OAuth2 Implementation Presentation (Java)
 
Supply chain security with Kubeclarity.pptx
Supply chain security with Kubeclarity.pptxSupply chain security with Kubeclarity.pptx
Supply chain security with Kubeclarity.pptx
 
Mastering Web Scraping with JSoup Unlocking the Secrets of HTML Parsing
Mastering Web Scraping with JSoup Unlocking the Secrets of HTML ParsingMastering Web Scraping with JSoup Unlocking the Secrets of HTML Parsing
Mastering Web Scraping with JSoup Unlocking the Secrets of HTML Parsing
 
Akka gRPC Essentials A Hands-On Introduction
Akka gRPC Essentials A Hands-On IntroductionAkka gRPC Essentials A Hands-On Introduction
Akka gRPC Essentials A Hands-On Introduction
 
Entity Core with Core Microservices.pptx
Entity Core with Core Microservices.pptxEntity Core with Core Microservices.pptx
Entity Core with Core Microservices.pptx
 
Introduction to Redis and its features.pptx
Introduction to Redis and its features.pptxIntroduction to Redis and its features.pptx
Introduction to Redis and its features.pptx
 

Recently uploaded

Welocme to ViralQR, your best QR code generator.
Welocme to ViralQR, your best QR code generator.Welocme to ViralQR, your best QR code generator.
Welocme to ViralQR, your best QR code generator.
ViralQR
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
Assure Contact Center Experiences for Your Customers With ThousandEyes
Assure Contact Center Experiences for Your Customers With ThousandEyesAssure Contact Center Experiences for Your Customers With ThousandEyes
Assure Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptxSecstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
nkrafacyberclub
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
DianaGray10
 
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
UiPathCommunity
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Thierry Lestable
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
sonjaschweigert1
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
Cheryl Hung
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
BookNet Canada
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Product School
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Paige Cruz
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
Thijs Feryn
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
Dorra BARTAGUIZ
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 

Recently uploaded (20)

Welocme to ViralQR, your best QR code generator.
Welocme to ViralQR, your best QR code generator.Welocme to ViralQR, your best QR code generator.
Welocme to ViralQR, your best QR code generator.
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
Assure Contact Center Experiences for Your Customers With ThousandEyes
Assure Contact Center Experiences for Your Customers With ThousandEyesAssure Contact Center Experiences for Your Customers With ThousandEyes
Assure Contact Center Experiences for Your Customers With ThousandEyes
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptxSecstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 

Object Equality in Scala

  • 1. Object Equality In Scala Ruchi Agarwal Software Consultant Knoldus
  • 2. Object Equality In Java & Scala: - Two equality comparisons: 1. == Operator 2. Equals() - The == operator, which is the natural equality for value types and object indentity for Refernce types in Java. // This is Java boolean isEqual(int x, int y){ return x == y; // Natural equality on value types } System.out.println(isEqual ( 421, 421)); //Output: True //java.lang.Integer(Object) boolean isEqual(Integer x, Integer y){ return x == y; // Reference equality on reference types } System.out.println(isEqual ( 421, 421)); //Output: False
  • 3. - The == equality is reserved in Scala for the “ Natural ” equality of each type. The equality operation == in scala is designed to be transparent with respect to the type's representation. - For value types, it is the natural (numeric or boolean) equality. - For reference types, == is treated as an alias of the equals() inherited from object. //This is Scala scala> def isEqual(x : Int , y : Int) = x == y isEqual: (x: Int, y: Int )Boolean scala> isEqual( 421 , 421) res8: Boolean = true scala> def isEqual(x : Any , y : Any) = x == y isEqual: (x: Any , y: Any)Boolean scala> isEqual( 421 , 421) res8: Boolean = true
  • 4. String Comparisons: - Scala, never fall into Java's well-known trap concerning string comparisons. //This is Scala scala> val x=“abcd”.substring(2) x: java.lang.String = cd scala> val y=“abcd”.substring(2) y: java.lang.String = cd scala> x == y res7: Boolean = true //This is Java boolean isEquals(String x, String y){ return x.substring(2) == y.substring(2); //return x.substring(2).equals(y.substring(2)); //Output: true } String s1="abcd"; String s2="abcd"; System.out.println(isEquals(s1, s2)); //Output: false
  • 5. Reference Equality: - For refernce equality, Scala's class AnyRef defines an additional eq method, which cannot be overridden and is implemented as reference equality(i. e., it behaves like == in Java for reference types). scala> val x=new String(“abc”) x: java.lang.String = abc scala> val x=new String("abc") x: java.lang.String = abc scala> x == y res13: Boolean = true // Value equality scala> x eq y res14: Boolean = false // Reference Equality - There's also the negation of eq , which is called ne. scala> x ne y res14: Boolean = true
  • 6. - For refernce equality, the behavior of == for new types can redefine by overriding the equals method, which is always inherited from class Any. - It is not possible to override == directly, as it is defined as a final method in class Any. // defination of == in Any class final def == (that : Any) : Boolean = if ( null eq this) { null eq that } else { this equals that }
  • 7. Writing an Equality Method: - Writing a correct equality method is surprisingly difficult in object-oriented languages. - This is problematic, because equality is at the basis of many other things. - Here are four common pitfalls that can cause inconsistent behavior when overriding equals: 1. Defining equals with wrong signature 2. Changing equals without also changing hashCode 3. Defining equals in terms of mutable fields 4. Failing to define equals as an equivalence relation
  • 8. Pitfall #1: Defining equals with wrong signature class Point ( val x:Int, val y :Int) { def equals (other: Point): Boolean = //Overloaded equals() this.x == other.x && this.y == other.y } scala> val p1, p2 = new Point (1 , 2) p1: Point = Point@1e0bb90 p2: Point = Point@139fb49 scala> val q= new Point( 2 , 3) q: Point = Point@a44ec3 //Working OK scala> p1 equals p2 res:0 Boolean : true scala> p1 equals q res:0 Boolean : false //Trouble scala> val p2a: Any = p2 // Alias of p2 p2a: Any = Point@139fb49 // p2a calling equals() of Any class scala> p1 equals p2a res:0 Boolean : false
  • 9. Solution: Correct Signature class Point ( val x:Int, val y :Int) { // A better definition:Overriding equals of Any class override def equals(other: Any) = other match { case that: Point => this.x == that.x && this.y == that.y case _ => false } } scala> val p2a: Any = p2 // Alias of p2 p2a: Any = Point@139fb49 scala> p1 equals p2a res:0 Boolean : true
  • 10. - A related pitfall is to define == with a wrong signature. - If try to redefine == with the correct signature, which takes an argument of type Any, the compiler will give an error because you try to override a final method of type Any. - However, newcomers to Scala sometimes make two errors at once: They try to override == and they give it the wrong signature. - For instance: def ==(other: Point): Boolean = // Don’t do this! (User-defined == method) - In that case, the user-defined == method is treated as an overloaded variant of the same-named method class Any, and the program compiles. - However, the behavior of the program would be just as dubious as if you had defined equals with the wrong signature.
  • 11. Pitfall #2: Changing equals without also changing hashCode //Previously defined equals method class Point ( val x:Int, val y :Int) { // A better definition:Overriding equals of Any class override def equals(other: Any) = other match { case that: Point => this.x == that.x && this.y == that.y case _ => false } } scala> import scala.collection.mutable._ import scala.collection.mutable._ scala> val p1, p2 = new Point (1 , 2) p1: Point = Point@1bef480 p2: Point = Point@1a6068c //storing p1 to collection scala> val coll = HashSet (p1) coll: scala.collection.mutable.Set[Point] = Set(Point@62d74e) scala> coll contains p2 res2: Boolean = false
  • 12. - In fact, this outcome is not 100% certain. We might also get true from the experiment. We can try with some other points with coordinates 1 and 2. Eventually, we’ll get one which is not contained in the set. hashSet(p1) contains p2 val p2 true val p1 val p2 false hashSet Hash Bucket Hash Bucket Pitfall #2: Changing equals without also changing hashCode
  • 13. - Wrong here is that Point redefined equals without also redefining hashCode. - The problem was that the last implementation of Point violated the contract on hashCode as defined for class Any: If two objects are equal according to the equals method, then calling the hashCode method on each of the two objects must produce the same integer result. - In fact, it’s well known in Java that hashCode and equals should always be redefined together. - Furthermore, hashCode may only depend on fields that equals depends on. - For the Point class, the following would be a suitable definition of hashCode: override def hashCode = 41 * (41 + x) + y // Redefine hashCode - This is just one of many possible implementations of hashCode. - Adding hashCode fixes the problems of equality when defining classes like Point.
  • 14. class Point(val x: Int, val y: Int) { override def hashCode = 41 * (41 + x) + y // Redefine hashCode override def equals(other: Any) = other match { // Redefine equals() case that: Point => this.x == that.x && this.y == that.y case _ => false } } scala> val p1, p2 = new Point(1, 2) p1: Point = Point@6bc p2: Point = Point@6bc scala> coll contains p2 res2: Boolean = true
  • 15. Pitfall #3: Defining equals in terms of mutable fields: - Consider the following slight variation of class Point: class Point2(var x: Int, var y: Int) { override def hashCode = 41 * (41 + x) + y // Redefine hashCode override def equals(other: Any) = other match { // Redefine equals() case that: Point2 => this.x == that.x && this.y == that.y case _ => false } } scala> val p = new Point(1, 2) p: Point = Point@2b scala> val coll = HashSet(p) coll: scala.collection.mutable.Set[Point] = Set(Point@2b) scala> coll contains p res5: Boolean = true scala> p.x += 1 // Changing p.x value scala> coll contains p res7: Boolean = false scala> coll.elements contains p res7: Boolean = true
  • 16. coll.elements contains p true p.x += 1 After change value it (x:mutable) assign to wrong hash bucket p.x=1 p.x=2 coll contains p coll false Hash Bucket Hash Bucket Pitfall #3: Defining equals in terms of mutable fields - In a manner of speaking, the point p “dropped out of sight” in the set coll even though it still belonged to its elements. - If you need a comparison that takes the current state of an object into account, you should usually name it something else, not equals.
  • 17. Pitfall #4: Failing to define equals as an equivalence relation: - In scala, Any class specifies that equals must implement an equivalence relation on non-null objects: • It is reflexive: for any non-null value x , the expression x.equals(x) should return true. • It is symmetric: for any non-null values x and y, x.equals(y) should return true if and only if y.equals(x) returns true. • It is transitive: for any non-null values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true. • It is consistent: for any non-null values x and y, multiple invocations of x.equals(y) should consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified. • For any non-null value x, x.equals(null) should return false. - The definition of equals developed so far for class Point satisfies the contract for equals. - However, things become more complicated once subclasses are considered.
  • 18. Symmetric Problem: class Point(val x: Int, val y: Int) { override def hashCode = 41 * (41 + x) + y // Redefine hashCode override def equals(other: Any) = other match { // Redefine equals() case that: Point => this.x == that.x && this.y == that.y case _ => false } } object Color extends Enumeration { val Red, Orange, Yellow, Green, Blue, Indigo, Violet = Value } class ColoredPoint(x: Int, y: Int, val color: Color.Value) extends Point(x, y) { // Problem: equals not symmetric override def equals(other: Any) = other match { case that: ColoredPoint =>this.color == that.color && super.equals(that) case _ => false } } scala> val p = new Point(1, 2) p: Point = Point@2b scala> val cp = new ColoredPoint(1, 2, Color.Red) cp: ColoredPoint =ColoredPoint@2b scala> p equals cp res:0 Boolean : true scala> cp equals p res:0 Boolean : false
  • 19. Solution of Symmetric Problem but violated Transitivity contract: class Point(val x: Int, val y: Int) { override def hashCode = 41 * (41 + x) + y // Redefine hashCode override def equals(other: Any) = other match { // Redefine equals() case that: Point => this.x == that.x && this.y == that.y case _ => false } } object Color extends Enumeration { val Red, Orange, Yellow, Green, Blue, Indigo, Violet = Value } class ColoredPoint(x: Int, y: Int, val color: Color.Value) extends Point(x, y) { // Problem: equals not transitive override def equals(other: Any) = other match { case that: ColoredPoint =>this.color == that.color && super.equals(that) case that:Point=>that equals this //new case to make symmetric case _ => false } } scala> p equals cp res:0 Boolean : true scala> cp equals p res:0 Boolean : true
  • 20. - Here’s a sequence of statements that demonstrates transitive. Define a point and two colored points of different colors, all at the same position: scala> var redp=new ColoredPoint(1,2,Color.Red) redp: ColoredPoint = ColoredPoint@6bc scala> var bluep=new ColoredPoint(1,2,Color.Blue) bluep: ColoredPoint = ColoredPoint@6bc scala> var p=new Point(1,2) p: Point = Point@6bc scala> redp == p res1: Boolean = true scala> p == bluep res1: Boolean = true scala> redp == bluep res1: Boolean = false - Hence, the transitivity clause of equals’s contract is violated. - One way to make equals stricter is to always treat objects of different classes as different. - That could be achieved by modifying the equals methods in classes Point and ColoredPoint. - In class Point, you could add an extra comparison that checks whether the run-time class of the other Point is exactly the same as this Point’s class, as follows:
  • 21. Solution of Transitivity Problem: class Point(val x: Int, val y: Int) { override def hashCode = 41 * (41 + x) + y // Redefine hashCode override def equals(that: Any) = other match { // Redefine equals() case that: Point => this.x == that.x && this.y == that.y && this.getClass == that.getClass case _ => false } } object Color extends Enumeration { val Red, Orange, Yellow, Green, Blue, Indigo, Violet = Value } class ColoredPoint(x: Int, y: Int, val color: Color.Value) extends Point(x, y) { override def equals(that: Any) = other match { case that: ColoredPoint =>(this.color == that.color)&& super.equals(that) case _ => false } } scala> redp == p res:0 Boolean : false scala> p == bluep res:0 Boolean : false scala> redp == bluep res:0 Boolean : false
  • 22. - Here, an instance of class Point is considered to be equal to some other instance of the same class only if the objects have the same coordinates and they have the same run- time class. - Meaning .getClass on either object returns the same value. - The new definitions satisfy symmetry and transitivity because now every comparison between objects of different classes yields false. - So a colored point can never be equal to a point.