Oracle equivalent sorting in Java

I want to sort java strings in alphabetical order. The sort should work similarly to the oracle order sql. I tried using java Collator, but it prioritizes small letters over capital letters. There are problems with non-English letters too ...

For instance:

select * from TABLE1 order by COLUMN1;

returns the rows in the following order: A, a, Á, á, Ä, ä, B, b, C, c (this is correct for me)

Collections.sort(strings, Collator.getInstance());

orders the following lines: a, A, á, ä, Ä, Á, b, B, c, C (there is a problem with the order of á, ä, Ä, Á)

(The locale is the same in both cases)

I do not want to type the whole alphabet, because I will forget the special letter. The application will be used by many different people from many European countries.

+4
3

. Oracle .

, , .. NLS_SORT. ,

SELECT SYS_CONTEXT ('USERENV', 'NLS_SORT') from SYS.DUAL;

, ,

A, a, Á, á, Ä, ä, B, b, C, c

, .

  • A A. . , A a, , .
  • , .

An NLS_SORT of GENERIC_M_CI . , :

[...] ORDER BY NLSSORT(<colname>, 'NLS_SORT=GENERIC_M_CI');

Java Collator setStrength(), PRIMARY, SECONDARY, TERTIARY IDENTICAL.

, javadocs

  • A b.
  • A á.
  • A A.
  • , .

, Collator SECONDARY .

en_US default :

List<String> strings = Arrays.asList("A", "Ä", "Á", "B", "C", "a", "á", "ä", "b", "c");
Collator collator = Collator.getInstance();
collator.setStrength(Collator.SECONDARY);
Collections.sort(strings, collator);
System.out.println(strings);

[A, a, Á, á, Ä, ä, B, b, C, c]

( A A, .)

+5

  Collator coll = Collator.getInstance(locale);
  coll.setStrength(Collator.PRIMARY) 
  Collections.sort(words, coll);

 List<String> words = Arrays.asList(
      "Äbc", "äbc", "Àbc", "àbc", "Abc", "abc", "ABC"
    );

    log("Different 'Collation Strength' values give different sort results: ");
    log(words + " - Original Data");
    sort(words, Strength.Primary);
    sort(words, Strength.Secondary);
    sort(words, Strength.Tertiary);

    private enum Strength {
    Primary(Collator.PRIMARY), //base char
    Secondary(Collator.SECONDARY), //base char + accent
    Tertiary(Collator.TERTIARY), // base char + accent + case
    Identical(Collator.IDENTICAL); //base char + accent + case + bits

    int getStrength() { return fStrength; }

    private int fStrength;
    private Strength(int aStrength){
      fStrength = aStrength;
    }
  }

  private static void sort(List<String> aWords, Strength aStrength){
    Collator collator = Collator.getInstance(TEST_LOCALE);
    collator.setStrength(aStrength.getStrength());
    Collections.sort(aWords, collator);
    log(aWords.toString() + " " + aStrength);
  }

:

Different 'Collation Strength' values give different sort results: 
[Äbc, äbc, Àbc, àbc, Abc, abc, ABC] - Original Data
[Äbc, äbc, Àbc, àbc, Abc, abc, ABC] Primary
[Abc, abc, ABC, Àbc, àbc, Äbc, äbc] Secondary
[abc, Abc, ABC, àbc, Àbc, äbc, Äbc] Tertiary

+1

1) , Oracle. oracleSort. , . . , Java- .

oracleSort = "AaÁáÄäBbCc..."

2) , , . http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Comparator.html , oracleSort. , , - .

oracleSort.indexOf( "a" ) 1.

oracleSort.indexOf( "Á" ) 2.

"a" , "Á"

3) , . , , , ASCII, .

Therefore, you can use Apache commons-lang StringUtils.stripAccents to create string copies without accents and capital letters. If they are equal, the comparison copies with accents, but in upper case. If they are equal, check each character to see if it has uppercase and one is lowercase.

public static int compare(String one, String two)
{
    String oneNoAccent = StringUtils.stripAccents(one).toUpperCase();
    String twoNoAccent = StringUtils.stripAccents(two).toUpperCase();
    int compare = oneNoAccent.compareTo(twoNoAccent);
    if(compare == 0)
    {
        String oneU = one.toUpperCase();
        String twoU = two.toUpperCase();
        compare = oneU.compareTo(twoU);
        if(compare == 0)
        {
            //TODO:
        }
    }
    return compare;
}
0
source

All Articles