Try the following example in an anonymous Apex window:

String s = '- Default - ';
system.debug(s.CompareTo('Banner')<0); // True
system.debug(s<'Banner'); // False
s = '/ Default -';
system.debug(s.CompareTo('Banner')<0); // True
system.debug(s<'Banner'); // true

Lexically, '- Default' is smaller than Banner because the '-' is smaller than 'B'. And the CompareTo operator works accordingly. But a regular string compare is treating the '-' seemingly as a special case, thus '- Default' is being treated as larger than 'Banner'. I'm guessing that Apex is treating the dash as a hyphen and excluding it from the comparison? It obviously isn't ignoring punctuation as evidenced by the '/' example.

I haven't yet found any documentation in the Apex reference or elsewhere that specifies what is going on here.

So my question is: Is this expected behavior, and if so, does anyone know where it is documented?

  • I had some VERY weird experiencing with string handling and an inbound email handler, where comparing two strings will return true, but if I try to cast the string to an Int it will fail, even though its a valid integer. – Steven Herod Jun 1 '13 at 9:48
  • Nice one! I played a bit, it behaves OK with test case narrowed down to '/', 'B', '-'. It starts to go bananas the moment you make '/x', 'Bx', '-x'. compareTo() returns same correct values in both cases (and they sort OK), it's "only" the < operator that acts weird. I've also noticed that '+' > '/' which is against ASCII table order. This stuff is so basic it should work irrespective of user's locale :/ – eyescream Jun 1 '13 at 23:31

The Apex docs do state that comparison of strings using <, >, <=, and >= is performed according to the user's locale.

Java has a class Collator which performs locale-sensitive string comparisons. I compiled this simple class and received the exact same results as your Apex less than comparisons:

import java.text.Collator;

public class TestCollator {
    public static void main(String[] args) {
        Collator myCollator = Collator.getInstance();
        System.out.println(myCollator.compare("- Default - ", "Banner") < 0); // False
        System.out.println(myCollator.compare("/ Default -", "Banner") < 0); // True

I am honestly not certain of the relationship between Apex and Java, but if Apex logical comparison of strings is implemented to follow the behavior of Java Collator, then I would venture a guess that the results of your Apex code are expected behavior. It's certainly not the result you or I would have expected without further documentation by Salesforce, but it seems plausible that it's the intended result.

  • Thanks - I think you got it. Definitely not obvious. – kibitzer Jun 4 '13 at 2:56

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.