Right way to Compare String in Java

The String is a special class in Java, so is String comparison. When I say comparing String variables, it can be either to compare two String object to check if they are same, i.e. contains same characters or compare them alphabetically to check which comes first or second. In this article, we are going to talk about the right way of comparing String variables, but what is the wrong way? The wrong way is to compare String using == operator. It is one area in which almost every Java programmer  has made mistakes sometimes by comparing two String variable using == operator. Many Java developers are exposed to string comparison very early in their Java journey,  It's often required in their first few programming assignments e.g. write a program to print hello if the user enters "John".  When you first start with String in Java, you create an object using String literal syntax e.g. name = "John" and then compare using == operator, you will get the right answer, but if you take same String as user input, you will not get the correct answer.  Why? because equality operator compares references i.e. if two reference variable points to the same object in the heap then it returns true, otherwise, it returns false.


How to compare String in Java

The right way of comparing String in Java is to either use equals(), equalsIgnoreCase(), or compareTo() method. You should use equals() method to check if two String contains exactly same characters in same order. It returns true if two String are equal or false if unequal. This happens because String class overrides equals() method from Object class, and this is the reason why behavior of == and equals() method varies in case of String but remains same in case of Object.


You should by default  use equals() whenever you want to check if they are same, but if you want to do case insensitive comparison then you should use method equalsIgnoreCase(), which is the counterpart of equals() and also present in java.lang.String class.

If you compare "iPhone" to "IPHONE" with equals() then it will return false, but equalsIgnoreCase() will return true, because both contains same characters only case is difference, one is mixed case while other is upper case.

By the way, if you want to compare multiple String objects in alphabetical order then you should use compareTo() method, which is especially for deciding the order of multiple String.

For example if you want to sort the list of String in Java, you can use compareTo() method for comparing each element to other. This method returns either positive, negative or zero depending upon whether the String on which it is called is greater than, less than or equal to passed String.

When I say greater than, I mean it comes later in the alphabetical order. For example when we compare "Java" to "C++" like "Java".compareTo("C++") it will return a positive number. If you reverse the order, then it will return a negative number.


Comparing String alphabetically in Java

here is complete example of comparing different String variables e.g. variable created using new() operator and String literals using == operator, equals() method, equalsIgnoreCase() and compareTo(). I have also put relevant comments to make the code more understandable.

import java.util.Arrays;
import java.util.List;


/**
 * Java Program to compare two String in Java. You should never use == operator for comparing
 * String to check equality, instead always use equals() or equalsIgnoreCase() method.
 * If you are not checking equality but just want to see which String comes first or second
 * in alphabetical order, then please use compareTo() command. 
 * 
 * @author WINDOWS 8
 */

public class StringCompareDemo {
   
    
    public static void main(String args[]){
        
        String a = "Java";
        String b = "C++";
        String c = "Scala";
        
        // let's see what happen when we compare String for equality using 
        // == operator, it will return true if both String point to same
        // object e.g. interned String or String literal, otherwise it
        // will return false, even if two String contains same characters
        // and has same length.
        
        if(a == "Java"){
            System.out.println("String literal can be compared using == operator");
        }
        
        // content is same but different object , == will return false
        String d = new String("Java"); 
        
        if(a != d){
            System.out.println("String liternal and new String should not be "
                    + "compared using == operator");
        }
        
        // two String object created using new also should not be
        // compared using == operator, it will return false
        // even if they have same content
        String e = new String("JavaScript");
        String f = new String("JavaScript");
        
        if(e != f){
            System.out.println("Two String has same content but pointing to different object");
        }
        
        
        // Right way to compare String in Java
        // if you want to check if two Strings are equal then use
        // equals() method
        if(a.equals("Java")){
            System.out.println("Both Strings contains same characters");
        }
        
        // when you use equals() method with literal, it's better to 
        // call equals() on String literal, this will help you to 
        // avoid NullPointerException
        if("Java".equals(a)){
            System.out.println("Right way of using equals() method with String literal");
        }
        
        // If you want to perform case insensitive comparison between
        // two String, then use equalsIgnoreCase() method of String class
        // it will return true if those contains same characters but in 
        // different case e.g. Java and JAVA will be equal if you use
        // equalsIgnoreCase() method
        String g = "JAVA";
        if(a.equalsIgnoreCase(g)){
            System.out.println("equalsIgnoreCase is used to perform case insensitive comparison");
        }
        
        
        // Now if you want to compare String to check their alphabetical order then
        // you should use compareTo() method. This method returns positive, negative and 0 if the
        // String on which it is called is greater than, less than or equal to 
        // passed String as parameter.
        if(a.compareTo(b) > 1){
            System.out.println(a + " comes after " + b + " in alphabetical order");
            
        }else if(a.compareTo(b) < -1){
            System.out.println(a + " comes before " + b + " in alphabetical order");
            
        }else{
            System.out.println(a + " and " + b + " are equal to each other");
        }
        
    }
   
}

Output
String literal can be compared using == operator
String liternal and new String should not be compared using == operator
Two String has same content but pointing to different object
Both Strings contains same characters
Right way of using equals() method with String literal
equalsIgnoreCase is used to perform case insensitive comparison
Java comes after C++ in alphabetical order
How to compare multiple String in Java alphabetically


Important points about String comparison

We have learned a lot of things but you will forget it very soon, no surprise :-) that's why revision is very important. let's recall few things which matter a lot.

1) You can compare two String variable using == operator but you should never do this because it will return true if you compare String literals but return false if you compare String object to a literal or two String object, even if they have same characters. Always remember, == operator returns true only if both variables points to the same object in the heap.

2) You should use equals() method to compare String variables if you want to check equality, this is the right way of comparing String in Java. String overrides equals() from Object and changes it's default behavior which was same as the == operator.

3) If you want to compare String without caring for case then you can use equalsIgnoreCase() method. This will return true even if you compare "java" to "JAVA", look one is the small case while other is in the capital case.

4) compareTo() is the method to use if you want to order multiple Strings in alphabetical order. You can use this method for sorting the list of String. It implements the natural order of String, which is alphabetic. This method comes from the Comparable interface.

5) When you use equal() or equalsIgnoreCase() method to compare a String literal or a known String object, which you sure is not null to compare with an unknown String object, call it on the literal or known object. This will prevent NullPointerException if that unknown String is null, because when compared with null equals() will return false, but if you call it on the null object, it will throw null pointer exception.


That's all about how do you compare String in Java. In short, there are three way to compare string object e.g. == operator, equals() and compareTo() method. Since == operator does memory level matching it's not appropriate to compare String which should be content based. equals() and equalsIgnoreCase() should be used to check only equality as it will return true and false, but cannot be used to check if one string is greater than or less than other. So right way to compare two string objects are by using compareTo() method, it is your only way to compare String in lexicographic order. So, for equality use equals() method and for comparison use compareTo() method.

1 comment:

  1. When you compare String to check equality, just use equals(), no point mixing == and equals(). If you need to sort list of String on custom order, use Comparator and override compare() method. For natural order, no need to do anything, just call sort() method.

    ReplyDelete