4

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?

2
  • 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. Jun 1, 2013 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, 2013 at 23:31

1 Answer 1

2

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.

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .