Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between being shallowly and deeply equal? How is this applied to caching?

Found the following in my notes, but I am unable to make sense of it:

Primitive type wrapper classes implement caching for a limited number of values.
This guarantees that a limited number of deeply equal wrapper objects are also shallowly equal: If o1.equals( o2 ) then o1 == o2.
For example, new Integer( 0 ) == new Integer( 0 ).
In general this does not always work.
For example, new Integer( 666 ) == new Integer( 666 )
may not hold.
The reason for caching is that it saves memory.
In general caching works for “small” primitive values.

I don't understand what is meant by this, or what the difference is between a deep (.equals()) and shallow(==) equals. I know in practice, .equals must be used to objects and == for Integral values, but the actual reasoning for this alludes me.

I assume by the names that shallow maybe just checks that both the values are of the same type and name, which deep checks that both variables point to the same object? I don't see how the caching would come into play here though, or why it would be useful.

like image 295
Albatross32 Avatar asked Apr 18 '11 13:04

Albatross32


People also ask

What is the difference between shallow and deep comparison?

And as you probably have guessed, shallow strategy compares superficially 2 operands equality — 1st level in depth only— while deep strategy compares the equality from all depth levels.

What is shallow equal and deep equal?

What you call "shallow equal" is identity: two references (i.e. objects) are identical if they are the very same instances. If you know what pointers are in other languages, you can compare identity to pointer equality. What you call "deep equal" is equality: two objects a and b are equal if a.

What is deeply equal?

deepEqual() method tests if two objects, and their child objects, are equal, using the == operator. If the two objects are not equal, an assertion failure is being caused, and the program is terminated. To compare the objects using the === operator, use the assert.

What is the difference between deep and shallow comparison in Java?

The equals() method provides “deep comparison” by checking if two objects are logically equal as opposed to the shallow comparison provided by the operator ==.


1 Answers

Well, actually shallow/deep dissection is different from ==/equal dissection:

  1. == compares for object identity, that is you checking whether operands are the same in fact (two references to the same area of memory), whereas equals compares for object equivalence, that is "logical" value of two, possibly not identical objects, is the same. If for two objects

    a == b
    

    then it's true that

    a.equals(b) // if a != null
    

    , but opposite isn't true in all cases.

  2. shallow/deep distinction makes sense only for equals comparison. Shallow means that you compare only immediate contents of two objects to find whether they "equal" in your sense, whereas deep means that you compare contents of your objects recursively until all you need to compare is primitive fields. If you define equals method of your objects as sequence of calls to equals on instance fields of these objects, you use deep comparison. If you define equals using == operator to compare compound types, such as Strings, then you use shallow comparison -- and that's incorrect in Java.

Morale of all of this is that you must never use == to compare two compound objects, unless you consider them equal only if they are the same.

like image 63
Victor Sorokin Avatar answered Nov 07 '22 08:11

Victor Sorokin