Most answers on the internet are incomplete and some are even plain wrong. I’ll try to list all differences.

# Short answer

- == checks if two expressions have the
*same value.* *equals*checks if two objects*represent*the same thing.

But that doesn’t really answer it. It is important to understand what those *values* are and what it means when two objects are equal. In a job interview you must give a short and precise answer but that is difficult for this question.

== basically checks if two expressions represent the same value and in most cases this means that the same bits and bytes are used to represent that value. But there are exceptions from this basic rules. I explain those later.

When you use == on two objects then you check for *identity*. Same identity simply means that two objects are the same (just one object). Java actually just applies == to the values of the references, without accessing the objects.

*equals* is used to check two objects for equality. This usually means that you could replace one for the other and that both should have the same hash code. Therefore an object is usually equal to itself. Equal Sets contain equal elements, equal Strings represent the same text, equal DateFormats represent the same format, and so on.

# Basic Definitions

(`x`

and `y`

are different variables with different memory content)

## == (Equality Operator)

- Compares values (primitives / references)
- == is an operator
`x == x`

can be`false`

!`x == y`

can be`true`

!- != is always the exact opposite of ==
- Two values/objects are:
*identical*(`5 == 5`

)- or
*distinct*(`"A" == "B"`

).

## equals (Method)

- Compares two objects (of any type)
`equals`

is a method- Default behaviour (without overriding implementation) is:
- x.equals(x) is true
- x.equals(y) is false
- x.equals(null) is false

- x.equals(x) can be false! x.equals(y) can be true!
- Two objects are:
*equal*(`"A".equals("A")`

)- or
*unequal/different*(`"A".equals("B")`

)

# Special Cases

There are exceptions and it is important to know them.

## Special Cases of ==

This operator sometimes doesn’t return what you might expect.

### Values of different Types can be considered identical

int i = 42; byte b = 42;

*i* and *b* are considered to be identical. But in memory they are different in size. Java will cast `b`

to `int`

and then compare two integers.

### NaN is not NaN

Double.NaN == Double.NaN // => false

This is false. But that’s just the nature of NaN. In this case the memory holds the same value.

The JVM even knows two types of NaN, but that isn’t relevant here.

### +0 is -0

+0.0 == -0.0 // => true

A double uses one bit for the sign (+/-). So the memory holds different values. But they are the same by definition.

### null is null

In contrast to NaN there is no special rule for null.

A variable that references null does not reference any valid object. In SQL the expression `NULL = NULL`

evaluates to false. But in Java you get true for `null == null`

. Why? Because!

### == is not = from Math Lessons

0.1+0.2 != 3.0/10.0

There is no precise representation of tenths in IEEE 754 floating point numbers. Therefore both expressions are actually a bit larger than 0.3, but not by the same amount.

To compare two floating point values you should always calculate the absolute difference and compare that to some *delta*.

double a = 0.1 + 0.2; double b = 3.0 / 10.0; double delta = 0.0000001; boolean equal = Math.abs(a - b) < delta;

## Special Cases of *equals*

This method sometimes doesn’t return what you might expect.

### Values of different Types can be equal

A proper implementation should define some type (class or interface) that needs to be used by two objects to be considered equal.

For example a HashSet can be equal to a TreeSet. But it only works if there is a common type that defines equality (in that case the java.util.Set interface).

In many other cases there is no such common type:

((Integer) 1).equals(1.0) // => false

Both are of type Number, but Integer would not consider any object to be equal that isn’t also an Integer.

String and int do not share any common type that would allow them to be equal, so the values are not equal.

"42".equals(42) // => false

### NaN equals NaN

((Double) Double.NaN).equals(Double.NaN) // => true

This is actually `true`

, even though `NaN != NaN`

…

### +0 and -0 are not equal

… but this is `false`

:

Double.valueOf(+0.0).equals(Double.valueOf(-0.0)) // => false

This is important so that all instances of Double can be used in Collections using equals (`Map`

, `Set`

).

### null

You get a NullPointerException for `null.equals(x)`

.

`x.equals(null)`

*should* return false.

# How to implement equals?

Just read the api specs:

http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-

It’s actually a bit more complex in some situations. Here’s a complete guide:

http://www.artima.com/lejava/articles/equality.html