Why is the uppercase not sorted correctly?

I am trying to sort List<String>

items. Here's unsorted List

and how it's currently sorted:

Unsorted: [Pineapple, pineapple, apple, apricot, Banana, mango, Mango, melon, peach]
Sorted: [apple, apricot, Banana, mango, Mango, melon, peach, Pineapple, pineapple]

      

Why Mango

does not fit in front Mango

and why Pineapple

before Pineapple

?

Here is my code:

import java.util.*;
import java.lang.*;
import java.io.*;

class Test {
    public static void main (String[] args) throws java.lang.Exception {
        List<String> fruits = new ArrayList<String>(7);

        fruits.add("Pineapple");
        fruits.add("pineapple");
        fruits.add("apple");
        fruits.add("apricot");
        fruits.add("Banana");
        fruits.add("mango");
        fruits.add("Mango");
        fruits.add("melon");        
        fruits.add("peach");

        System.out.println("Unsorted: " + fruits);

        Collections.sort(fruits, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {              
                return o1.compareToIgnoreCase(o2);
            }
        });

        System.out.println("Sorted: " + fruits);
    }
}

      

+3


source to share


5 answers


As a comparison method was used compareToIgnoreCase()

, so it was comparing "Pineapple" and "Pineapple" as 0 (same string), leaving them in the order they were found when sorting, since Collections.sort makes sure that equal elements won reordering ... In other words, "Pineapple" appeared before "pineapple", so now that they are equal to the ropes due to ignore, "Pineapple" will remain before "pineapple".



Since the unsorted list has Pineapple before Pineapple, the comparison puts them in the sorted list in the same order. The same rules apply for "mango" and "mango". The comparison method you're looking for is just one compareTo()

that counts both upper and lower case letters.

+4


source


Why doesn't "Mango" fit in front of "mango" and why "Pineapple" before "pineapple"?

According to your comparator, "Mango" and "Mango" compare are equal. Since stable , elements comparing the same are equal are returned in the order they were found in the original collection (an unstable sort will return them in no particular order).Collections.sort()

If you expect Mango to always be returned before Mango, your comparator needs to reflect that. This means that "Mango" should be compared less than "mango" (but more than "apple", "apricot", "banana", etc.).

One way to achieve this is with the following comparator:



Collections.sort(fruits, new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {              
        int ret = o1.compareToIgnoreCase(o2);
        if (ret == 0) {
            ret = o1.compareTo(o2);
        }
        return ret;
    }
});

      

This will return:

Sorted: [apple, apricot, Banana, Mango, mango, melon, peach, Pineapple, pineapple]

      

+2


source


Because you are using compareToIgnoreCase

which, as the name says, ignores case when comparing two strings. So, mango and mango are the same and they are left in the same order as they were (the sort is stable, for example: the equality element remains in the order in which they were before the sort.).

On the side of the note, you are comparing the same as String.CASE_INSENSITIVE_ORDER . compareToIgnoreCase

simplifications call this comparator.

+2


source


According to the javadocs it is Collections.sort

guaranteed to be stable - the relative order of elements that are compared as equal is not changed by the sort. If you want to enforce orders that place uppercase letters in front of their lowercase equivalents, you need to use a different comparator that implements that ordering, the simplest way to implement that is likely to be java.text.RuleBasedCollator

.

0


source


You are doing everything right.

"mango" must really precede "pineapple" and "apple".

But "pineapple" and "pineapple" are "the same." Smooth. "0". Because you said "ignoreCase".

-1


source







All Articles