View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All

String Comparison in Java: Methods, Examples, and Best Practices

Updated on 28/04/20255,157 Views

Introduction

String comparison in Java Programming is a fundamental operation that every Java programmer must master. Whether you're validating user input, sorting text, or implementing search functionality, knowing how to properly compare strings is essential. In this guide, we'll explore all the string comparison methods in Java, examine best practices, and provide practical examples to help you handle string comparisons effectively in your applications.

Dreaming of going pro in Java? Learn from the best with upGrad’s immersive software engineering course.

Understanding String Comparison in Java

Strings in Java are objects, not primitive types, which means comparing them requires special consideration. Java provides several ways to compare strings, each with its own purpose and behavior:

  1. Using the equals() method
  2. Using the == operator
  3. Using the compareTo() method
  4. Using the equalsIgnoreCase() method
  5. Using the regionMatches() method
  6. Using the contentEquals() method
  7. Using Apache Commons StringUtils methods

Let's explore each of these string comparison methods in Java in detail.

Advance your career with top AI and data science courses:

• M.Sc. in AI & Data Science – Jindal Global University

• Master’s in Data Science – LJMU

• PG Diploma in ML & AI – IIIT Bangalore

How to Do String Comparison in Java: Different Methods

1. The equals() Method

The equals() method compares the actual content (character by character) of the strings and is the most commonly used method for string comparison in Java.

public class EqualsExample {
    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = "Hello";
        String str3 = new String("Hello");
        
        // Content comparison using equals()
        System.out.println("str1.equals(str2): " + str1.equals(str2));
        System.out.println("str1.equals(str3): " + str1.equals(str3));
        
        // Example of using null-safe comparison
        String nullString = null;
        String emptyString = "";
        
        // This would throw NullPointerException
        // System.out.println(nullString.equals(emptyString));
        
        // Null-safe comparison
        System.out.println("Objects.equals(nullString, emptyString): " + 
                           java.util.Objects.equals(nullString, emptyString));
    }
}

Expected Output:

str1.equals(str2): true

str1.equals(str3): true

Objects.equals(nullString, emptyString): false

Explanation:

  • equals() compares string contents, so both comparisons return true since all strings contain "Hello"
  • Using Objects.equals() provides a null-safe way to compare strings, avoiding NullPointerException

Must check: Difference between equals method in Java

2. The == Operator

The == operator compares object references, not content. For strings, it checks if two references point to the same object in memory.

public class ReferenceComparisonExample {
    public static void main(String[] args) {
        String str1 = "Java";
        String str2 = "Java";  // Uses string pool, same reference as str1
        String str3 = new String("Java");  // Creates new object, different reference
        
        // Reference comparison using ==
        System.out.println("str1 == str2: " + (str1 == str2));
        System.out.println("str1 == str3: " + (str1 == str3));
        
        // Demonstrating string pool behavior
        String str4 = "Hello ";
        String str5 = "World";
        String str6 = "Hello World";
        String str7 = "Hello " + "World";  // Compile-time constant, uses string pool
        String str8 = str4 + str5;  // Runtime concatenation, new object
        
        System.out.println("str6 == str7: " + (str6 == str7));
        System.out.println("str6 == str8: " + (str6 == str8));
        System.out.println("str6.equals(str8): " + str6.equals(str8));
    }
}

Expected Output:

str1 == str2: true

str1 == str3: false

str6 == str7: true

str6 == str8: false

str6.equals(str8): true

Explanation:

  • str1 and str2 refer to the same object in the string pool
  • str3 is a new object with its own memory location
  • str7 is a compile-time constant and uses the string pool
  • str8 is created at runtime and is a new object

Check out: Top 13 String Functions in Java | Java String [With Examples]

3. The compareTo() Method

The compareTo() method compares strings lexicographically (dictionary order) and returns an integer:

  • Negative value if string1 comes before string2
  • Zero if strings are equal
  • Positive value if string1 comes after string2
public class CompareToExample {
    public static void main(String[] args) {
        String str1 = "apple";
        String str2 = "banana";
        String str3 = "apple";
        String str4 = "Apple";  // Capital 'A' has a different ASCII value
        
        // Lexicographic comparison
        System.out.println("str1.compareTo(str2): " + str1.compareTo(str2));
        System.out.println("str2.compareTo(str1): " + str2.compareTo(str1));
        System.out.println("str1.compareTo(str3): " + str1.compareTo(str3));
        System.out.println("str1.compareTo(str4): " + str1.compareTo(str4));
        System.out.println("str1.compareToIgnoreCase(str4): " + str1.compareToIgnoreCase(str4));
        
        // Using compareTo() for sorting
        String[] fruits = {"banana", "apple", "grape", "cherry"};
        Arrays.sort(fruits);
        System.out.println("Sorted fruits: " + Arrays.toString(fruits));
        
        // Using compareTo() for custom objects
        Person p1 = new Person("Alice", 30);
        Person p2 = new Person("Bob", 25);
        System.out.println("p1.compareTo(p2): " + p1.compareTo(p2));
    }
    
    static class Person implements Comparable<Person> {
        private String name;
        private int age;
        
        Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
        
        @Override
        public int compareTo(Person other) {
            // Compare by name
            return this.name.compareTo(other.name);
        }
        
        @Override
        public String toString() {
            return name + " (" + age + ")";
        }
    }
}

Expected Output:

str1.compareTo(str2): -1

str2.compareTo(str1): 1

str1.compareTo(str3): 0

str1.compareTo(str4): 32

str1.compareToIgnoreCase(str4): 0

Sorted fruits: [apple, banana, cherry, grape]

p1.compareTo(p2): -1

Explanation:

  • "apple" comes before "banana" alphabetically, so compareTo() returns a negative value
  • "banana" comes after "apple", so it returns a positive value
  • The same strings return 0
  • Case-sensitive comparison returns a non-zero value
  • Case-insensitive comparison with compareToIgnoreCase() returns 0
  • Array sorting uses compareTo() internally
  • Custom objects can implement Comparable to define natural ordering

Must explore: How to Sort a String in Java

4. The equalsIgnoreCase() Method

The equalsIgnoreCase() method compares strings while ignoring case differences.

public class EqualsIgnoreCaseExample {
    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = "hello";
        String str3 = "HELLO";
        
        // Case-insensitive comparison
        System.out.println("str1.equals(str2): " + str1.equals(str2));
        System.out.println("str1.equalsIgnoreCase(str2): " + str1.equalsIgnoreCase(str2));
        System.out.println("str1.equalsIgnoreCase(str3): " + str1.equalsIgnoreCase(str3));
        
        // Practical example: case-insensitive user input validation
        String userInput = "YES";
        System.out.println("User confirmed: " + userInput.equalsIgnoreCase("yes"));
        
        String email1 = "User@Example.com";
        String email2 = "user@example.com";
        System.out.println("Emails match: " + email1.equalsIgnoreCase(email2));
    }
}

Expected Output:

str1.equals(str2): false

str1.equalsIgnoreCase(str2): true

str1.equalsIgnoreCase(str3): true

User confirmed: true

Emails match: true

Explanation:

  • Regular equals() is case-sensitive and returns false
  • equalsIgnoreCase() ignores case differences and returns true
  • This is useful for user input validation where case shouldn't matter

Also read: Strings in Java Vs Strings in C++

5. The regionMatches() Method

The regionMatches() method compares portions of strings and can optionally ignore case.

public class RegionMatchesExample {
    public static void main(String[] args) {
        String str1 = "Hello, World!";
        String str2 = "HELLO, Java!";
        
        // Compare regions with case sensitivity
        boolean result1 = str1.regionMatches(0, str2, 0, 5);
        System.out.println("Case-sensitive region match: " + result1);
        
        // Compare regions ignoring case
        boolean result2 = str1.regionMatches(true, 0, str2, 0, 5);
        System.out.println("Case-insensitive region match: " + result2);
        
        // Practical example: check if email ends with a domain
        String email = "user@example.com";
        String domain = "EXAMPLE.COM";
        boolean isDomainMatch = email.regionMatches(
            true, // ignore case
            email.indexOf('@') + 1, // start after '@'
            domain, 
            0, // start of domain
            domain.length() // length to compare
        );
        System.out.println("Email domain matches: " + isDomainMatch);
    }
}

Expected Output:

Case-sensitive region match: false

Case-insensitive region match: true

Email domain matches: true

Explanation:

  • The case-sensitive region comparison fails because of case differences
  • The case-insensitive comparison (with true as the first parameter) succeeds
  • The method is useful for comparing specific portions of strings, like email domains

Also explore: String Length in Java

6. The contentEquals() Method

The contentEquals() method compares a string with any CharSequence (String, StringBuilder, StringBuffer, etc.).

public class ContentEqualsExample {
    public static void main(String[] args) {
        String str = "Java Programming";
        
        // Compare with StringBuilder
        StringBuilder sb = new StringBuilder("Java Programming");
        System.out.println("str.contentEquals(sb): " + str.contentEquals(sb));
        
        // Compare with StringBuffer
        StringBuffer sbuf = new StringBuffer("Java Programming");
        System.out.println("str.contentEquals(sbuf): " + str.contentEquals(sbuf));
        
        // Compare with different content
        sb.append(" Language");
        System.out.println("After modification - str.contentEquals(sb): " + str.contentEquals(sb));
        
        // Compare with CharBuffer
        CharBuffer cb = CharBuffer.wrap(new char[] {'J', 'a', 'v', 'a', ' ', 
                                                 'P', 'r', 'o', 'g', 'r', 'a', 
                                                 'm', 'm', 'i', 'n', 'g'});
        System.out.println("str.contentEquals(cb): " + str.contentEquals(cb));
    }
}

Expected Output:

str.contentEquals(sb): true

str.contentEquals(sbuf): true

After modification - str.contentEquals(sb): false

str.contentEquals(cb): true

Explanation:

  • contentEquals() allows comparison with any CharSequence implementation
  • It compares the content regardless of the actual type of the sequence
  • Unlike equals(), it doesn't require both objects to be strings

7. Using StringUtils (Apache Commons)

Apache Commons Lang provides StringUtils with additional comparison capabilities.

// Note: Requires Apache Commons Lang library
import org.apache.commons.lang3.StringUtils;

public class StringUtilsExample {
    public static void main(String[] args) {
        // Null-safe comparison
        String str1 = null;
        String str2 = "test";
        
        // Regular equals would throw NullPointerException
        // System.out.println(str1.equals(str2)); // Throws exception
        
        // StringUtils null-safe comparison
        System.out.println("StringUtils.equals(): " + StringUtils.equals(str1, str2));
        
        // Case-insensitive comparison
        String str3 = "HELLO";
        String str4 = "hello";
        System.out.println("StringUtils.equalsIgnoreCase(): " + 
                          StringUtils.equalsIgnoreCase(str3, str4));
        
        // Comparison with nulls as empty
        System.out.println("StringUtils.equalsAny(): " + 
                          StringUtils.equalsAny(str2, "test", "other", null));
        
        // Check if string contains another string (case insensitive)
        System.out.println("StringUtils.containsIgnoreCase(): " + 
                          StringUtils.containsIgnoreCase("Hello World", "world"));
    }
}

Expected Output:

StringUtils.equals(): false

StringUtils.equalsIgnoreCase(): true

StringUtils.equalsAny(): true

StringUtils.containsIgnoreCase(): true

Explanation:

  • StringUtils provides null-safe operations
  • It offers additional utility methods like equalsAny() and containsIgnoreCase()
  • These utilities help make code more robust and concise

String Array Comparison in Java

Comparing arrays of strings requires special approaches.

public class StringArrayComparisonExample {
    public static void main(String[] args) {
        String[] array1 = {"apple", "banana", "cherry"};
        String[] array2 = {"apple", "banana", "cherry"};
        String[] array3 = {"apple", "cherry", "banana"};
        
        // Using Arrays.equals() - compares elements in order
        System.out.println("Arrays.equals(): " + Arrays.equals(array1, array2));
        System.out.println("Arrays.equals() different order: " + Arrays.equals(array1, array3));
        
        // Deep comparison for nested arrays
        String[][] nestedArray1 = {{"a", "b"}, {"c", "d"}};
        String[][] nestedArray2 = {{"a", "b"}, {"c", "d"}};
        System.out.println("Arrays.deepEquals(): " + Arrays.deepEquals(nestedArray1, nestedArray2));
        
        // Comparing as lists
        List<String> list1 = Arrays.asList(array1);
        List<String> list2 = Arrays.asList(array2);
        List<String> list3 = Arrays.asList(array3);
        
        System.out.println("list1.equals(list2): " + list1.equals(list2));
        
        // Comparing regardless of order
        System.out.println("Same elements, different order: " + 
                          new HashSet<>(list1).equals(new HashSet<>(list3)));
        
        // Check if array contains a string
        String searchString = "banana";
        System.out.println("Contains \"" + searchString + "\": " + 
                          Arrays.asList(array1).contains(searchString));
    }
}

Expected Output:

Arrays.equals(): true

Arrays.equals() different order: false

Arrays.deepEquals(): true

list1.equals(list2): true

Same elements, different order: true

Contains "banana": true

Explanation:

  • Arrays.equals() compares elements in order
  • Arrays.deepEquals() handles nested arrays
  • Converting to List or Set provides additional comparison options
  • Using HashSet allows order-insensitive comparison

Must read: Char array to string in java

String Character Comparison in Java

For character-level operations, Java provides several methods.

public class StringCharacterComparisonExample {
    public static void main(String[] args) {
        String str = "Hello";
        
        // Compare individual characters
        char firstChar = str.charAt(0);
        System.out.println("First character: " + firstChar);
        System.out.println("Is 'H'?: " + (firstChar == 'H'));
        
        // Check if string starts with character
        System.out.println("Starts with 'H': " + str.startsWith("H"));
        
        // Check if string ends with character
        System.out.println("Ends with 'o': " + str.endsWith("o"));
        
        // Find index of character
        System.out.println("Index of 'e': " + str.indexOf('e'));
        
        // Count occurrences of a character
        String text = "programming";
        char target = 'm';
        long count = text.chars().filter(ch -> ch == target).count();
        System.out.println("Count of '" + target + "': " + count);
        
        // Compare characters case-insensitively
        char ch1 = 'a';
        char ch2 = 'A';
        System.out.println("Case-insensitive character comparison: " + 
                          (Character.toLowerCase(ch1) == Character.toLowerCase(ch2)));
    }
}

Expected Output:

First character: H

Is 'H'?: true

Starts with 'H': true

Ends with 'o': true

Index of 'e': 1

Count of 'm': 2

Case-insensitive character comparison: true

Explanation:

  • charAt() accesses individual characters
  • startsWith() and endsWith() check string boundaries
  • indexOf() finds character positions
  • Streams can be used for advanced character operations
  • Character class provides utilities for character manipulation

Best Practices for String Comparison in Java

1. Use equals() for Content Comparison

Always use equals() when comparing string content, not the == operator.

// GOOD:
if (string1.equals(string2)) { /* ... */ }

// BAD:
if (string1 == string2) { /* ... */ }

2. Handle Null Values Safely

Prevent NullPointerException by using null-safe comparison methods.

// GOOD:
if (Objects.equals(string1, string2)) { /* ... */ }

// Or place the known non-null string first:
if ("expected".equals(userInput)) { /* ... */ }

// BAD:
if (userInput.equals("expected")) { /* ... */ } // NPE if userInput is null

3. Use Case-Insensitive Comparison When Appropriate

For user input or when case doesn't matter, use case-insensitive methods.

// GOOD for user inputs, commands, etc.
if (userCommand.equalsIgnoreCase("quit")) { /* ... */ }

// BAD if case-sensitivity matters (like passwords)
if (password.equalsIgnoreCase(expectedPassword)) { /* ... */ }

4. Choose the Right Comparison for the Task

Select the appropriate method based on your needs.

// For exact equality:
if (string1.equals(string2)) { /* ... */ }

// For sorting:
Collections.sort(strings, String::compareTo);

// For partial matching:
if (string1.regionMatches(true, 0, string2, 0, 5)) { /* ... */ }

5. Consider Performance for Repeated Comparisons

For frequent comparisons, consider performance optimizations.

// LESS EFFICIENT: Creating temporary uppercase strings
if (string1.toUpperCase().equals(string2.toUpperCase())) { /* ... */ }

// MORE EFFICIENT: Using method that doesn't create new strings
if (string1.equalsIgnoreCase(string2)) { /* ... */ }

Advanced String Comparison Techniques

Pattern Matching with Regular Expressions

For complex string matching, regular expressions provide powerful tools.

public class RegexComparisonExample {
    public static void main(String[] args) {
        String email = "user@example.com";
        
        // Simple regex for email validation
        String emailPattern = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$";
        boolean isValidEmail = email.matches(emailPattern);
        System.out.println("Is valid email: " + isValidEmail);
        
        // Pattern matching with groups
        String date = "2023-04-15";
        Pattern datePattern = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})");
        Matcher matcher = datePattern.matcher(date);
        
        if (matcher.matches()) {
            String year = matcher.group(1);
            String month = matcher.group(2);
            String day = matcher.group(3);
            System.out.println("Date parts: " + year + ", " + month + ", " + day);
        }
        
        // Case-insensitive pattern matching
        String text = "Java Programming Language";
        Pattern pattern = Pattern.compile("java", Pattern.CASE_INSENSITIVE);
        Matcher matcherCase = pattern.matcher(text);
        System.out.println("Contains 'java' (case-insensitive): " + matcherCase.find());
    }
}

Expected Output:

Is valid email: true

Date parts: 2023, 04, 15

Contains 'java' (case-insensitive): true

Explanation:

  • Regular expressions provide powerful string matching capabilities
  • Pattern and Matcher classes offer advanced functionality
  • Case-insensitive matching can be achieved with pattern flags

Collator for Locale-Specific Comparison

For international applications, use Collator to handle locale-specific comparisons.

public class CollatorExample {
    public static void main(String[] args) {
        String str1 = "café";
        String str2 = "cafe";
        
        // Default string comparison
        System.out.println("equals(): " + str1.equals(str2));
        
        // Using Collator for locale-specific comparison
        Collator frCollator = Collator.getInstance(Locale.FRENCH);
        System.out.println("French collator (primary): " + (frCollator.compare(str1, str2) == 0));
        
        // Setting strength for different sensitivity levels
        frCollator.setStrength(Collator.PRIMARY);  // Ignores accents and case
        System.out.println("Primary strength: " + (frCollator.compare(str1, str2) == 0));
        
        frCollator.setStrength(Collator.SECONDARY);  // Sensitive to accents, ignores case
        System.out.println("Secondary strength: " + (frCollator.compare(str1, str2) == 0));
        
        frCollator.setStrength(Collator.TERTIARY);  // Sensitive to accents and case
        System.out.println("Tertiary strength: " + (frCollator.compare(str1, str2) == 0));
        
        // Sorting with locale sensitivity
        String[] words = {"côte", "cote", "côté", "coté"};
        Arrays.sort(words, frCollator);
        System.out.println("Sorted with French collator: " + Arrays.toString(words));
    }
}

Expected Output:

equals(): false

French collator (primary): false

Primary strength: true

Secondary strength: false

Tertiary strength: false

Sorted with French collator: [cote, côte, coté, côté]

Explanation:

  • Collator provides locale-sensitive string comparison
  • Different strength levels control sensitivity to accents, case, etc.
  • This is crucial for properly handling international text

Conclusion

Choosing the right string comparison method in Java is crucial for writing accurate and efficient code. Use equals() for content matching, compareTo() for ordering, and case-insensitive methods when needed. For internationalization, rely on tools like Collator. Understanding the difference between reference and content comparison helps avoid subtle bugs and ensures your Java applications handle text processing reliably across different use cases.

FAQs

1. What is the difference between equals() and == when comparing strings?

The equals() method compares the actual content of strings (character by character), while the == operator compares object references (whether two variables point to the same object in memory). For string comparison, equals() is almost always what you want.

2. How do I perform case-insensitive string comparison in Java?

Use the equalsIgnoreCase() method for direct comparison, or compareToIgnoreCase() for sorting order comparison. For more complex scenarios, consider using toLowerCase() or toUpperCase() with equals(), or Pattern with case-insensitive flags.

3. Why does "Hello" == "Hello" return true but new String("Hello") == "Hello" return false?

Java maintains a string pool for string literals. When you write "Hello" twice, both reference the same object in the pool. But new String("Hello") explicitly creates a new object outside the pool, resulting in different references even though the content is identical.

4. How can I compare strings for natural order sorting?

Use the compareTo() method, which compares strings lexicographically (dictionary order). For case-insensitive sorting, use compareToIgnoreCase(). For locale-sensitive sorting, use Collator with the appropriate locale.

5. How do I safely compare strings when one might be null?

Use Objects.equals(string1, string2) for null-safe comparison. Alternatively, place the known non-null string first: "expectedValue".equals(possiblyNullString). You can also use utilities like Apache's StringUtils.equals().

6. How can I compare specific portions of two strings?

Use the regionMatches() method, which allows you to compare substrings starting at specified offsets. It also provides an option for case-insensitive comparison.

7. What's the most efficient way to check if a string is empty?

Use the isEmpty() method for checking emptiness, and isBlank() (Java 11+) for checking if a string is empty or contains only whitespace. For null-safe checks, combine with a null check or use utilities like StringUtils.isEmpty().

8. How do I compare strings ignoring whitespace?

You can use str1.trim().equals(str2.trim()) to ignore leading and trailing whitespace. For more complex whitespace handling, consider using regular expressions with replaceAll("\\s+", "") before comparison.

9. Is string comparison in Java affected by Unicode encoding?

Yes, Java strings are stored in UTF-16 encoding, so some Unicode characters (like emojis or characters outside the Basic Multilingual Plane) are represented by surrogate pairs. Methods like length(), charAt(), and substring() operate on code units, which may not correspond directly to characters. For proper Unicode handling, use the codePointCount() and related methods.

10. What's the performance impact of different string comparison methods?

The == operator is fastest but only checks references. The equals() method has to check each character but short-circuits on length differences. For large strings, hashCode() comparison first may improve performance. The compareTo() method is generally slower as it needs to determine ordering, not just equality.

11. How can I compare strings while ignoring accents or diacritical marks?

Use java.text.Collator with the appropriate strength level. Collator.PRIMARY ignores accents and case differences, making it useful for accent-insensitive comparisons across different languages and locales.

12. Which method should I use to compare strings for database queries?

For most database operations, use equals() for exact matching and compareTo() for ordering. For case-insensitive queries, use equalsIgnoreCase() or wrap both strings in toLowerCase() before comparison. For more complex pattern matching, consider using database-specific functions or JDBC prepared statements.

image

Take the Free Quiz on Java

Answer quick questions and assess your Java knowledge

right-top-arrow
image
Join 10M+ Learners & Transform Your Career
Learn on a personalised AI-powered platform that offers best-in-class content, live sessions & mentorship from leading industry experts.
advertise-arrow

Free Courses

Explore Our Free Software Tutorials

upGrad Learner Support

Talk to our experts. We are available 7 days a week, 9 AM to 12 AM (midnight)

text

Indian Nationals

1800 210 2020

text

Foreign Nationals

+918068792934

Disclaimer

1.The above statistics depend on various factors and individual results may vary. Past performance is no guarantee of future results.

2.The student assumes full responsibility for all expenses associated with visas, travel, & related costs. upGrad does not provide any a.