☰ Contents How Java Runs

Checking Contents vs Checking Identity

Student: OK, so can we ever compare the contents of strings or arrays?
Prof: Absolutely! Many objects have a method called equals that helps with this. So for strings, just use s1.equals(s2) instead of s1 == s2. That’s actually what’s happening with records and strings in assertEquals:
Student: Oh, OK. So I should always use .equals()?
Prof: Well, we may see some cases where we want reference equality. We don’t have any right now. So it’s true, we mostly care about the .equals() kind, which is called structural equality (it inspects the structure). But we can’t get rid of == entirely because we need it for comparing, say, int values. Those are called primitive types, as opposed to objects which are reference types, and they compare the numbers themselves with ==.
Student: Hmm I see. OK so we need == for numbers. What about arrays? You didn’t give an example of structural equality for those.
Prof: It’s a little trickier there. Arrays’ equals method checks reference equality, not structural. So there’s actually a separate helper for arrays called Arrays.equals; it takes two array arguments and compares them structurally. And JUnit has a separate assertArrayEquals.
Student: But why?
Prof: Well, part of the issue is that because arrays can change, two arrays could have the same contents at one point in the program, but differ later.
Student: Huh?
Prof: Because of array update, which we saw in the last section. Here, I’ll show you:
Prof: So one way I think about it is that Java makes sure that .equals() between arrays only returns true if they are the same reference, because that’s the only way to guarantee that they will always be the same now and in the future. If they are different references, it could change. So you have to use Arrays.equals to “opt-in”, and acknowledge that you know you mean “equal right now”. The final memory diagram at the point the assertion fails looks like this:
Names (the stack)
main()
nums1 = @1001
nums2 = @1002
top level
Heap
@1001: [6, 7]
@1002: [999, 7]
Student: Hmm, that seems like a lot to remember.
Prof: It is. The main thing to think through is what you’re asking in an equality check. If it involves objects (which includes String), reach for .equals(). If it involves arrays, there may be more to check.
Student: I’ll have to sit with that a little bit.

Practice

Each pair below holds the same contents, built separately. Pick the check that gives true for each pair:

record Point(int x, int y) { }
int a = 6 + 7;
int b = 13;
String trash = "trash";
String s1 = "trash panda";
String s2 = trash + " panda";
Point p1 = new Point(4, 5);
Point p2 = new Point(4, 5);
int[] n1 = { 6, 7 };
int[] n2 = { 6, 7 };
boolean sameInts = ;
boolean sameStrings = ;
boolean samePoints = ;
boolean sameArrays = ;