Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When does the "==" operator successfully compare strings? [duplicate]

I understand that the equality operator compares references to the strings. So, it will check to see if the strings refer to the same object and not if they are equal character by character.

As a first step in learning about search algorithms, I set up the following program where I have an array of names and then I check if a certain name appears in the array.

First Approach :

I declare and initialize the array of the names. And I ask the user to input a name to check if it appears in the array.

Here's the code I used -

import java.util.Scanner;

public class Strawman{

    public static void main(String[] args){

        System.out.println("Enter the name to search for:");

        Scanner scanner = new Scanner(System.in);
        String key = scanner.nextLine();

        String[] names = {"alice", "bob", "carlos", "carol", "craig", "dave", "erin", "eve", "frank", "mallory", "oscar", "peggy", "trent", "walter", "wendy"};

        for (int i = 0; i < names.length; i++){

            if (key == names[i]) {
                System.out.println("Index " + i + " has the name " + key);
            } 
        }
    }

}

One of the runs of this program is shown in the following screenshot - program output

As expected, because I'm using the == operator to compare strings, this fails to find the name "oscar" in the array, even though it appeared in the initial array. This output is as expected based on my understanding of how equality operators compares references of the strings.

But, I don't understand why the program seems to work if instead of asking for user input, I declare the name to search for as a string.

Second Approach:

The name "oscar" to search for has been declared as a string instead of asking for user input -

public class Strawman2{

    public static void main(String[] args){

        String[] names = {"alice", "bob", "carol", "craig", "carlos", "dave", "eve", "fred", "greg", "gregory", "oscar", "peter"};
        String key = "oscar";

        for (int i = 0; i < names.length; i++){

            if (names[i] == key){
                System.out.println("Index " + i + " has name " + key);
            }

        }

    }

}

Now, if I run the program, the name "oscar" is found in the array - output_approach2

Can someone explain the difference in the two cases?

like image 581
Ratus Avatar asked May 15 '26 16:05

Ratus


2 Answers

It's because in the second approach

String key = "oscar";

reuses an instance from the string constant pool populated by

String[] names = {"alice", "bob", "carol", "craig", "carlos", "dave", "eve", "fred", "greg", "gregory", "oscar", "peter"};

Change the way you initiate key variable into:

String key = new String("oscar");

it will behave the same way as first approach as you bypass the String Constant Pool and your key variable will now refer to another object in memory.

For more information about the String Constant Pool: String Constant Pool

like image 93
Allan Avatar answered May 17 '26 05:05

Allan


It's because the compiler reuses string instances from string literals that are known at compile time. Hence they pass the object equality check. Reuse is possible because Strings are immutable objects.

Strings that are not know at compile time, and/or explicitly created as new String objects, are not subject to this optimisation and will always result in new objects.

like image 35
ig-dev Avatar answered May 17 '26 06:05

ig-dev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!