user3652239
user3652239

Reputation: 21

Java - How to order capital letters before lowercase letters using CompareTo method

Let's say, for example that I have the same 2 strings but the first one starts with capital letter and the second one isn't. Now, I need to order capital letters before lowercase letters using CompareTo method. How do I do that? because CompareTo method will order them the opposite way.

An Example: List = { "world","Aple","World", "aple","Hello"} the order I want to get is: "Aple","Hello","World", "aple", "world". Meaning, no matter what, uppercase letters come first.

Upvotes: 1

Views: 7292

Answers (5)

Syam S
Syam S

Reputation: 8499

Try

public class StringSorter {

    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("apple");
        list.add("Hello");
        list.add("Apple");
        list.add("World");
        list.add("hello");

        Collections.sort(list,
                new Comparator<String>() {

                    @Override
                    public int compare(String o1, String o2) {
                        if(o1.equalsIgnoreCase(o2)){
                            return o1.compareTo(o2);
                        }
                        return o1.toUpperCase().compareTo(o2.toUpperCase());
                    }

                });

        System.out.println(list);

        // in a shorter way with java-8
        list.sort(Comparator.comparing(String::toLowerCase));
    }

}

Upvotes: 3

Mani
Mani

Reputation: 3364

I liked Syam S answer. And thought of trying in different way. I believe it is comparatively efficient too

Off course - add null check :)

Collections.sort(list,
            new Comparator<String>() {

        @Override
        public int compare(String o1, String o2) {
            int min = Math.min(o1.length(), o2.length());
            for (int k = 0; k < min ; k++ ){
                char c1 = o1.charAt(k);
                char c2 = o2.charAt(k);
                if (c1 != c2 ){
                    char u1 = Character.toUpperCase(c1);
                    char u2 = Character.toUpperCase(c2);
                    if (u1 == u2) {
                        return Character.isUpperCase(c1) ? -1 : 1;
                    }else{
                        return u1 - u2;
                    }
                }
            }

            return o1.length() - o2.length();
        }

    });

Upvotes: 0

OldCurmudgeon
OldCurmudgeon

Reputation: 65793

Something like this should work - I am tinkering with the returns so it may change.

static class CasedStringComparator implements Comparator<String> {

    @Override
    public int compare(String o1, String o2) {
        if ( o1 == null ) {
            return -1;
        }
        if ( o2 == null ) {
            return 1;
        }
        for ( int i = 0; i < Math.min(o1.length(), o2.length()); i++ ) {
            char c1 = o1.charAt(i);
            char c2 = o2.charAt(i);
            if ( Character.isUpperCase(c1) && !Character.isUpperCase(c2)) {
                return -1;
            }
            if ( !Character.isUpperCase(c1) && Character.isUpperCase(c2)) {
                return 1;
            }
            int diff = Character.compare(c1, c2);
            if (diff != 0) {
                return diff;
            }
        }
        if ( o1.length() < o2.length() ) {
            return -1;
        }
        return 0;
    }
}

But as @GriffeyDog points out - this does not change the default ordering which also puts uppercase before lowercase.

Upvotes: 0

Tim Cooper
Tim Cooper

Reputation: 10468

Here's a(the) standard implementation of string comparisons:

public int compareTo(String anotherString) {
    int len1 = value.length;
    int len2 = anotherString.value.length;
    int lim = Math.min(len1, len2);
    char v1[] = value;
    char v2[] = anotherString.value;

    int k = 0;
    while (k < lim) {
        char c1 = v1[k];
        char c2 = v2[k];
        if (c1 != c2) {
            return c1 - c2;
        }
        k++;
    }
    return len1 - len2;
}

You'll need to write a method like this that changes the char values, e.g. swapping uppercase and lowercase. Then as netinept says, use it in a sort algorithm as a 'compareTo' override or 'Comparable' implementation.

Upvotes: 0

Kyle Falconer
Kyle Falconer

Reputation: 8490

Override the compareTo method or implement the Comparable Interface.

The documentation says that the return value for this is

-1, 0, or 1 according to whether the value of expression is negative, zero or positive.

So, you only need to do your own string comparisons and return the appropriate value.

Upvotes: 1

Related Questions