The idea of "stack" and "heap" is incoherent in my view. It is best not to think in those terms.
The real difference is between
locations that are named by (variable) symbols in the program (call
them named locations) and
locations (or groups of locations) whose references are stored in
other locations (call them referenced locations).
If you want, you can think of named locations sitting in a "stack" and referenced locations sitting in a "heap". But that would be mere terminology. It does not reflect what an implementation might actually do.
In Java, when you declare an integer variable:
you are creating a named location. An integer such as 23, say, will be stored in that location. Note that only one location is created!
On the other hand, when you declare an integer array:
you are creating a named location
a and, in addition, a block of 10 referenced locations for the elements of the array. The named location
a stores a reference to the block of the 10 locations. (Note that 11 locations are now created. In addition to the 10 locations for the array elements, an extra location for the reference to the array!) This corresponds to the picture that you have drawn in the question. For integer variables, there is no reference stored anywhere. So, your picture is wrong for integer variables.
I think of Java as an extremely confusing language from this point of view. The declarations
int i; and
int a; look so similar, but what they mean is entirely different!
Coming back to the question, when you compare two integer variables using
i == j", you are asking "are the integers stored in the two named locations the same?". When you compare two array variables using
a == b, you are asking the question "are the references stored in the two named locations a and b the same?" If a and b store references to two different blocks of locations both of which might contain the same integers, the comparison
a == b would still come out false. Why? The comparison
a == b doesn't look at the actual blocks of locations at all. It just checks to see whether they are the same block. This kind of thing is often called reference equality or shallow equality.
It is not really your fault if you are totally confused. When hackers design programming languages, this is the kind of mess they create!