3.7. Comparing Objects

Comparing objects is a little different than comparing primitive typed values like numbers. Objects can be very complex and have many attribute values or instance variables inside them. For example, the turtle objects have many instance variables like name, width, height, xPos, yPos, etc. When comparing two turtle objects, we need a specially written equals method to compare all of these values. In this lesson, we will take a look at String objects and how they are compared.

3.7.1. String Equality

With String objects, you must use the equals method to test if two strings have the same characters in the same order instead of == which is used for primitive types.

When the operator == is used with object variables it returns true when the two variables refer to the same object. These variables are called aliases for the same object and object references. With strings this happens when one string variable is set to another or when strings are set to the same string literal. Only use == to test if two strings refer to the same object. Most of the time you will want to use equals and not == with strings.

coding exercise Coding Exercise

The one common place to use == or != with objects is to see if they exist by comparing them to null. Sometimes short-circuit evaluation is used to avoid an error if the object doesn’t exist. Remember that short-circuit evaluation is used with && in Java meaning that if the first part of the if condition is false, it doesn’t even have to check the second condition and it knows the whole && test is false. Try the following code to see a NullPointer error. Since s is null, indexOf throws an NullPointer error for s. Comment out the first if statement and run the program again. The second if statement avoids the error with shortcircuit evaluation. Because s != null is false, the rest of the boolean expression is not evaluated. Now, change s to set it to “apple” instead of null in the first line and run the code again to see that the if statements can print out that “apple contains an a”.

If you run the following, what will be printed?

It will print Bye since s3 has been assigned to a copy of the value in s2 which is an object reference to the String object that has the characters “Bye” in it. In addition, s2 == s3 will be true since the two variables refer to the same object. Also, s2.equals(s3) will also be true, again since the two variables refer to the same object, of course the characters will be the same.

../_images/stringRefExamplev2.png

Figure 1: Several String variables with references to objects of the String class.

3.7.2. Using new with Strings

If you use the new keyword to create a string it will create a new string object. So, even if we create two string objects with the same characters using the new operator they will not refer to the same object. What will the following print?

Since we used the new keyword two different String objects will be created that each have the characters Hello in them. So s1 == s2 will be false since they don’t refer to the same object, but s1.equals(s2) is true since the two different object contain the same characters in the same order.

../_images/twoStringRefsv2.png

Figure 2: Two string variables and two string objects that contain the same characters in the same order.

3.7.3. Using String Literals

What do you think the following code will print? Run it to check.

Since we used string literals this time rather than the new keyword, the Java run-time will check if that string literal already exists as an object in memory, and if so reuse it. So s1 and s2 will refer to the same string object. That means that both == and equals will be true.

../_images/twoStringRefsLiteral.png

Figure 3: Two string variables that refer to the same string literal.

exercise Check your understanding

    3-7-1: Which of the following is true after the code executes?

    String s1 = new String("hi");
    String s2 = "bye";
    String s3 = "hi";
    s2 = s1;
    
  • s1 == s2 && s1 == s3
  • Do s1 and s3 refer to the same object?
  • s1 == s2 && s1.equals(s3)
  • Yes s2 was set to refer to the same object as s1 and s1 and s3 have the same characters.
  • s1 != s2 && s1.equals(s3)
  • Did you miss that s2 was set to refer to the same object as s1?

    3-7-2: Which of the following is true after the code executes?

    String s1 = "hi";
    String s2 = "bye";
    String s3 = "hi";
    
  • s1 == s2 && s1 == s3
  • Do s1 and s2 refer to the same object?
  • s2.equals(s3) && s1.equals(s3)
  • Does s2 have the same characters as s1 or s3?
  • s1 != s2 && s1 == s3
  • Because you used the same string literal s1 and s3 will refer to the same object. Since s1 and s2 refer to different string literals they do not refer to the same object.

    3-7-3: Which of the following is true after the code executes?

    String s1 = "hi";
    String s2 = "bye";
    String s3 = new String("hi");
    
  • s1 == s3 && s1.equals(s3)
  • Since s3 uses the new operator it will not refer to the same object as s1.
  • s2.equals(s3) && s1.equals(s3)
  • Do s2 and s3 have the same characters in the same order?
  • !(s1 == s2) && !(s1 == s3)
  • All of the variables refer to different objects. But, s1.equals(s3) would be true since they have the same characters in the same order.

3.7.4. groupwork Programming Challenge : Tracing Code

What will the following code print out? Trace through the code by drawing diagrams of what is going on in memory like the figures above, and then show the values of s1, s2, s3, s4 and the output after each line of code. Remember that you can use trace tables to track the values of variables as they change throughout a program. To trace through code, write down a variable in each column in a table and keep track of its value throughout the program as you go through it line by line.

String s1 = null;
String s2 = new String("hi");
String s3 = new String("hi");
String s4 = "hi";
if (s1 == null)
    s1 = s2;
if (s1 == s2)
   System.out.println("s1 and s2 refer to the same object");
if (s2 == s3)
   System.out.println("s2 and s3 refer to the same object");
if (s3 == s4)
   System.out.println("s3 and s4 refer to the same object");
if (s1.equals(s2) && s2.equals(s3) && s3.equals(s4))
    System.out.println("s1, s2, s3, s4 are equal");

3-7-4: Write your tracing table here that keeps track of s1, s2, s3, s4 and the output.

3.7.5. Summary

  • Often classes have their own equals method, which can be used to determine whether two objects of the class are equivalent.

  • Two object references are considered aliases when they both reference the same object.

  • Object reference values can be compared, using == and !=, to identify aliases.

  • A reference value can be compared with null, using == or !=, to determine if the reference actually references an object.

You have attempted of activities on this page
Next Section - 3.8. Unit 3 - Summary