37
if ('text'.equals(str))

or

if ('text' == str)

Is there any difference? If yes, then what is it?



Added, after answered.

String q = 'teXt';
system.debug('teXt'.equals(q)); // true
system.debug('teXt' == q);      // true
system.debug('text'.equals(q)); // false
system.debug('text' == q);      // true
46

Yes there is a major difference, Case sensitivity.

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_string.htm

> equals(stringOrId) Returns true if the passed-in object is not null and represents the same binary sequence of characters as the current string. Use this method to compare a string to an object that represents a string or an ID.

== is same as equalsIgnoreCase(secondString)

Returns true if the secondString is not null and represents the same sequence of characters as the String that called the method, ignoring case.

1
  • 1
    Hi, is there any doc that says that "== is the same as equalsIgnoreCase"? If so, please add it to your post. Cheers Jun 20 '19 at 10:08
33

I would add that == is more null safe. Consider the following examples.

String a;
String b = null;
system.assert(a == b);

This will pass.

String a;
String b = null;
system.assert(a.equals(b));

This will throw a null pointer exception.

The above demonstration is why I tend to prefer == over .equals. If you are going to use .equals, you should always first check that it is not null, though it is not necessary when using constants.

final String SOME_CONSTANT = 'abc';
...
if (SOME_CONSTANT.equals('abc'))
{
    // do stuff
}
if (someParameter == SOME_CONSTANT)
{
    // do other stuff
}

Also note that while .equals is case sensitive, you can still call .equalsIgnoreCase.

In addition to what I've already stated, I did some informal profiling and it seems == may be significantly faster than .equals. More than 7 times as fast.

.equals

String a = 'abc';
String b = 'abc';
DateTime start = Datetime.now();
for (Integer i = 0; i < 100000; i++) Boolean isEqual = a.equals(b);
Decimal interval = Datetime.now().getTime() - start.getTime();
system.debug(interval); // yields 1831

.equalsIgnoreCase

String a = 'abc';
String b = 'abc';
DateTime start = Datetime.now();
for (Integer i = 0; i < 100000; i++) Boolean isEqual = a.equalsIgnoreCase(b);
Decimal interval = Datetime.now().getTime() - start.getTime();
system.debug(interval); // yields 1514

==

String a = 'abc';
String b = 'abc';
DateTime start = Datetime.now();
for (Integer i = 0; i < 100000; i++) Boolean isEqual = a == b
Decimal interval = Datetime.now().getTime() - start.getTime();
system.debug(interval); // yields 239

Even the slowest of these is consuming less than 1/5 ms per execution, but if you get in a big loop and your calls start to number in the millions, that can add up.

1
  • 5
    Good point about performance. Will keep this in mind. Thanks! Jun 20 '15 at 12:41
3

Side note:My actual comment starts below in the next paragraph, I tried to add just a comment to the answer above me related to the statements about the speed of the == versus .equals() methods but I need 50 points to comment yet I'm allowed to answer, even though my answer which is related to the other answer would be much better as an 'in thread' comment. Regardless....

As Adrian I'm sure knows, you need to be very careful when doing performance comparisons as a lot of things can affect the timing, from methods not being 'warmed' up, to incorrectly setup performance tests, to timing the wrong thing and inadvertently timing other functionality beyond what you thought.

As an example I ran the exact same code above (for the .equals()/.equalsIgnoreCase()/== timings) a total of 50 times to try and get an 'average' value (for some form of average). After 50 runs of each of the 3 tests and with each doing 100,000 loops per for loop I ended up with times for the .equals() and .equalsIgnoreCase() methods that are within a few percent of each other so for simplicity here I'm treating them as the same and showing the average value for them.

.equals/.equalsIgnoreCase = ~815ms (ranging in tests from 650 to 909)
using the 2equal signs == = ~467ms (ranging in tests from 350 to 838)

So the performance timings I get (after a total 50 test runs) indicates about a roughly 75% improvement using the == over the .equalsIgnoreCase() however that is a long way away from the 700%/7x mentioned above.

Also, I've put the min and max times that I got next to each of the times as well as this just goes to show how inaccurate/variable the performance timing testing can be. Although there was roughly a 75% improvement on average using '==' in some tests the times could vary so much that it would actually be slower than the .equalsIgnoreCase() methods.

Further, I was running 5 lots of the 3 tests each time and collecting 5 lots of 3 sets of values after every run. If there was load on my laptop during these test runs it could greatly effect the times and cause a time on one/many of the test cases to blow out greatly. To try to minimise this I would have no other apps/programs/tools running/processing at the same time and once the test was started/running I would not move the mouse, click, perform any kind of input until the test completed. I also decided that as part of my methodology that if even a single test case blew out in terms of time because of load then I would completely exclude ALL 5 sets of 3 test results in that run and re-run. In some of these test runs where there was load on the laptop during the test runs I would be getting times of 1000, 2000, 3000ms and more which was multiple times above the final averages.

So, to sum up, what I'm trying to get at is that performance figures need to be carefully obtained and handed up with a large number of caveats usually. I do agree with Adrian in that the '==' method of comparison of Strings in Apex is actually quicker although perhaps no where near 7 times faster but somewhere closer to less than twice as fast. It also gives you null safety in situations like:

String a = null;
String b = 'foo';
System.debug('       a==b =' + (a==b));                  // false
System.debug('a.equals(b) =' + (a.equalsIgnoreCase(b))); // Null Pointer Exception
System.debug('a?.equals(b)=' + (a?.equalsIgnoreCase(b)));// null

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.