Java中的Oracle等效排序

use*_*545 4 java sql sorting oracle sql-order-by

我想按字母顺序对Java字符串进行排序.排序应该类似于Oracle SQL order by.我曾尝试使用Java Collat​​or,但它优先考虑大字母上的小写字母.非英文字母也存在问题......

例如:

select * from TABLE1 order by COLUMN1;
Run Code Online (Sandbox Code Playgroud)

按以下顺序返回字符串:A,a,Á,á,Ä,ä,B,b,C,C(对我来说是正确的)

Collections.sort(strings, Collator.getInstance());
Run Code Online (Sandbox Code Playgroud)

订购这样的字符串:a,A,á,ä,Ä,Á,b,B,C,C(á,ä,Ä,Á顺序有问题)

(两种情况下的语言环境相同)

我不想输入整个字母表,因为我会忘记一些特别的字母.来自许多欧洲国家的许多不同的人将使用该申请.

flu*_*lup 5

排序很复杂.在Oracle文档给出了不同方面的完整概述.

很高兴知道你要重现的确切排序,即确切的值NLS_SORT.你可以通过执行找到

SELECT SYS_CONTEXT ('USERENV', 'NLS_SORT') from SYS.DUAL;
Run Code Online (Sandbox Code Playgroud)

你正在使用的那种产生

A, a, Á, á, Ä, ä, B, b, C, c
Run Code Online (Sandbox Code Playgroud)

目前尚不清楚输入的顺序是什么.

  • 它放在A前面a.这很奇怪.我推断它实际上并不是优先选择A而是认为它们是相同的,即不区分大小写.
  • 它在带有重音的字母之前添加了非重音字母,所以我推断它的重音敏感.

一个NLS_SORTGENERIC_M_CI符合本条例草案.您可以在oracle中运行它来检查:

[...] ORDER BY NLSSORT(<colname>, 'NLS_SORT=GENERIC_M_CI');
Run Code Online (Sandbox Code Playgroud)

一个Java分页器具有setStrength()它接受值的方法PRIMARY,SECONDARY,TERTIARYIDENTICAL.

确切的解释取决于语言环境,但javadocs给出了一个例子

  • 主要优势区分ab仅区分.
  • 次要力量也区分aá.
  • 三级强度也区分aA.
  • 只有字符绝对相同才能满足相同的强度.

所以一个有力量SECONDARY的Collat​​or应该可以为你服务.

在我的机器上,使用en_US默认语言环境,我尝试了这个:

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);
Run Code Online (Sandbox Code Playgroud)

打印

[A, a, Á, á, Ä, ä, B, b, C, c]
Run Code Online (Sandbox Code Playgroud)

(但如果你把它放在a前面A,它就会保持原状.)


Pro*_*ock 0

1) 您需要一个表示 Oracle 排序顺序的字符串。我将此字符串称为 oracleSort。\n您可以尝试在互联网上搜索此字符串,或者\n您可以将每个字母的一行插入数据库,查询该列并获取结果。根据结果​​组装您的排序字符串。这听起来很费力,但您也可以使用 Java 程序来填充数据库。

\n\n

oracleSort = "Aa\xc3\x81\xc3\xa1\xc3\x84\xc3\xa4BbCc..."

\n\n

2)我认为您需要实现一个比较两个字符串的比较器。\n http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Comparator.html \n逐字符进行遍历字符串并比较 oracleSort 中找到的字符索引。索引小于其相应位置的第一个字符是较小的字符串。

\n\n

oracleSort.indexOf("a") 是 1。

\n\n

oracleSort.indexOf("\xc3\x81") 是 2。

\n\n

“a”小于“\xc3\x81”

\n\n

3)后来我想可能还有其他的模式。看起来顺序是按不带重音符号的字母分组,然后按 ASCII 大写字母排序,然后是大写字母,然后是小写字母。

\n\n

因此,您可以使用 Apache commons-lang StringUtils.stripAccents 来制作不带重音符号和大写字母的字符串副本。如果它们相等,则比较带有重音符号但大写的副本。如果它们相等,则检查每个字符,看看是否有一个是大写,一个是小写。

\n\n
public static int compare(String one, String two)\n{\n    String oneNoAccent = StringUtils.stripAccents(one).toUpperCase();\n    String twoNoAccent = StringUtils.stripAccents(two).toUpperCase();\n    int compare = oneNoAccent.compareTo(twoNoAccent);\n    if(compare == 0)\n    {\n        String oneU = one.toUpperCase();\n        String twoU = two.toUpperCase();\n        compare = oneU.compareTo(twoU);\n        if(compare == 0)\n        {\n            //TODO:\n        }\n    }\n    return compare;\n}\n
Run Code Online (Sandbox Code Playgroud)\n