6

I need to compare 2 Strings. I have following methods I could think of:

  1. equalsIgnoreCase - Heard that this is the fastest, but i can't use it as my String is case sensitive
  2. matches - Probably the slowest one
  3. equals
  4. compareTo

So in the above option, I am left with equals and compareTo. Which one is faster among these?

Note: Input number of Strings are huge in number [around 5000 per sec].

G.S
  • 10,413
  • 7
  • 36
  • 52
  • 3
    I very much doubt that `equalsIgnoreCase` is faster than others. Must be slower because it needs to do more. – Thilo Oct 21 '13 at 06:40
  • Any specific reason why equals is faster? – G.S Oct 21 '13 at 06:40
  • 1
    equals is very fast for strings of different length. – Thilo Oct 21 '13 at 06:40
  • Best way to find out is to measure it. Note that the situation may change with different platform versions. – Henry Oct 21 '13 at 06:41
  • Could you explain what you are doing? What Strings are you comparing? I think it really depends on the situation (i.e. if you compare strings already in the string pool or if you compare new ones). compareTo will not be #1 because it has to check if the incoming object is a String first and will then (propabbly through the equals method) check if the Strings are equal. – Chris Oct 21 '13 at 06:42
  • Why just not to run test code and check what is better in your particular case? – dbf Oct 21 '13 at 06:43
  • @G.S It doesn't matter which is faster. What you're doing is micro-optimization, the actual slow parts in your program are elsewhere. – Kayaman Oct 21 '13 at 06:45
  • `String#equals` and `String#compareTo` are of the same complexity. You should use the one you deem more appropriate for the situation. – Ben Barkay Oct 21 '13 at 06:46
  • 1
    possible duplicate of [What's the quickest way to compare strings in Java?](http://stackoverflow.com/questions/3805601/whats-the-quickest-way-to-compare-strings-in-java) – devnull Oct 21 '13 at 06:47
  • Also see [this](http://stackoverflow.com/questions/1339870/fastest-way-to-compare-strings-literal-and-numerical). – devnull Oct 21 '13 at 06:48
  • Just *use the "correct" comparison based on what is needed* (it sounds like `equals`). 5000/second is likely *nothing* for a modern CPU (although one come point to degenerate data cases). If there is a performance bounds issue it will be due to another algorithm selection or bottleneck (where are your profile numbers?!?). I honestly don't understand why such micro-optimization questions (*that can be tested*) get so much [positive] attention .. – user2864740 Oct 21 '13 at 07:34
  • possible duplicate of [Java Strings: compareTo() vs. equals()](http://stackoverflow.com/questions/1551235/java-strings-compareto-vs-equals) – Raedwald Oct 23 '13 at 07:04

8 Answers8

13

Note a very important difference between compareTo and equals:

"myString".compareTo(null);  //Throws java.lang.NullPointerException
"myString".equals(null);     //Returns false

Now I advise you to review the source code of both methods to conclude that equals is preferable over compareTo that involves some Math calculations.

Also note that equals makes a == first! This might be a big advantage when the objects are identical. Specially when you mentioned that you have a huge amount of Strings, because Java interns Strings, this might happen more than you thought.


Although you asked about Strings, but I want to add this note:
These methods can be very different when BigDecimal is involved. For example, see the docs:

equals compares this BigDecimal with the specified Object for equality. Unlike compareTo, this method considers two BigDecimal objects equal only if they are equal in value and scale (thus 2.0 is not equal to 2.00 when compared by this method).

Maroun
  • 94,125
  • 30
  • 188
  • 241
6

I am left with equals and compareTo.

Both serves in different purposes.

CompareTo

the value 0 if the argument string is equal to this string; a value less than 0 if this string is lexicographically less than the string argument; and a value greater than 0 if this string is lexicographically greater than the string argument.

Where as

equals

true if the given object represents a String equivalent to this string, false otherwise

Hence compareTo() need more calculations that equals()

You can see the proof of that in source code of both.

compareTo()

equals() ----- prefer to use this.

Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
  • Actually, looking at the source code of both methods it appears that `String#compareTo` is of the same complexity as `String#equals`. – Ben Barkay Oct 21 '13 at 06:45
  • @BenBarkay It's not always about complexity. For example, `equals` first uses `==`, which is much faster when the Strings are identical. – Maroun Oct 21 '13 at 06:55
  • @MarounMaroun it's true, but if you ever get to the point where you repeatedly compare a string with itself to make this a significant performance gain, the real problem is likely to be something other than your choice of comparison method. – Ben Barkay Oct 21 '13 at 07:02
  • @BenBarkay Indeed. But since Java `intern` Strings, the `==` comparison might be happening more than we thought :) – Maroun Oct 21 '13 at 07:06
2

equalsIgnoreCase

You generally use this one for string comparison.

matches

Slow because it is RegEx-based.

equals

I don't think this is slower than equalsIgnoreCase

compareTo

This returns an integer, or 0. This is used in sorting, for example. Don't use it for equality.

Georgian
  • 8,795
  • 8
  • 46
  • 87
1

The 2 main differences are that:

equals will take any Object as a parameter, but compareTo will only take Strings.
equals only tells you whether they're equal or not, but compareTo gives information on how the Strings compare lexicographically.

ANd this is the class code url http://www.docjar.com/html/api/java/lang/String.java.html. U can also look at this post if u want Java Strings: compareTo() vs. equals()

Community
  • 1
  • 1
Asif Mahamud
  • 583
  • 2
  • 10
1

Equals -

1- Override the GetHashCode method to allow a type to work correctly in a hash table.

2- Do not throw an exception in the implementation of an Equals method. Instead, return false for a null argument.

3-

 x.Equals(x) returns true.

 x.Equals(y) returns the same value as y.Equals(x).

 (x.Equals(y) && y.Equals(z)) returns true if and only if x.Equals(z) returns true.

Successive invocations of x.Equals(y) return the same value as long as the object referenced by x and y are not modified.

 x.Equals(null) returns false.

4- For some kinds of objects, it is desirable to have Equals test for value equality instead of referential equality. Such implementations of Equals return true if the two objects have the same value, even if they are not the same instance.

For Example -

  Object obj1 = new Object();
  Object obj2 = new Object();
  Console.WriteLine(obj1.Equals(obj2));
  obj1 = obj2; 
  Console.WriteLine(obj1.Equals(obj2)); 

Output :-

  False
  True

while compareTo -

Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object.

It returns -

Less than zero - This instance precedes obj in the sort order. Zero - This instance occurs in the same position in the sort order as obj. Greater than zero - This instance follows obj in the sort order.

It can throw ArgumentException if object is not the same type as instance.

For example you can visit here.

So I suggest better to use Equals in place of compareTo.

Prabhat Jain
  • 346
  • 1
  • 8
0

You can time the code yourself and see which is faster:

final long start = System.currentTimeMillis();
for (int i = 0; i < input.length; i++) {
  // Do comparison here
}
final long end = System.currentTimeMillis();

System.out.println("Time to execute: " + (end - start));
Scott Helme
  • 4,786
  • 2
  • 23
  • 35
0

s1.CompareTo(s2)

0 - both equal

+ve - than s2 is lexicographically lower than the s1

-ve - than s2 is lexicographically higher than the s1

s1.equals(Object o1)

true- if s1 and o1 equals

false- if s1 and o1 not equal

compareTo can throw ClassCastException but equals if s1 and o1 are different class than should return false.


TreeMap depends on compareTo() while HashMap depends on equals(). So if you equals and compareTo are not consistent than TreeMap and HashMap can behave differently. Hence it is good to have equals() and compareTo() consistent to each other but it's not mandatory.


I think the best or efficient way to compare string is to reference compare (but you should have used literals in your whole code). Because string inherently immutable and String class implements FlyWeight pattern inside by intern() method or by compiler. So it is good to compare reference.

if you are not confident about literals in code than you can do an optimization:

s1.hashCode() == s2.hashCode() && s1.equals(s2)

This is because String in immutable.

Trying
  • 14,004
  • 9
  • 70
  • 110
0

equalsIgnoreCase - Heard that this is the fastest

Definitely not. It has to do things to promote lowercase to uppercase or vice versa. You can't have 'heard' that anywhere reputable.

matches - Probably the slowest one

Agreed.

equals compareTo

There is no reason to expect a difference between these.

user207421
  • 305,947
  • 44
  • 307
  • 483