java 阿拉伯语_用Java排序阿拉伯语单词

博主试图使用RuleBasedCollator对阿拉伯语单词列表进行排序,但遇到问题。通过创建自定义规则字符串并尝试不同语言环境的Collator,排序结果不正确。最后发现只需使用内置的Collator.getInstance(new Locale("ar"))即可解决阿拉伯语排序问题,提高了效率。
摘要由CSDN通过智能技术生成

我有一份阿拉伯语单词列表,我想对其进行排序.我尝试过使用不同语言环境的标准Collat​​or(如英语或法语但没有太多希望),我甚至创建了自己的RuleBasedCollat​​or但无济于事.显然,默认排序依赖于unicode值顺序,这在许多情况下有效,但显然不在这个顺序中.

遵循javadocs的说明,RuleBasedCollat​​or需要一个字符串,按照您希望它们排序的顺序指定字符.我使用this table中的unicode代码创建了以下字符串:

String arabicLetters = "< \u0623=\uFE83=\uFE84 < \u0628=\uFE8F=\uFE90=\uFE92=\uFE91 < \u062A=\uFE95=\uFE96=\uFE98=\uFE97 < \u062B=\uFE99=\uFE9A=\uFE9C=\uFE9B < \u062C=\uFE9D=\uFE9E=\uFEA0=\uFE9F < \u062D=\uFEA1=\uFEA2=\uFEA4=\uFEA3 < \u062E=\uFEA5=\uFEA6=\uFEA8=\uFEA7 < \u062F=\uFEA9=\uFEAA < \u0630=\uFEAB=\uFEAC < \u0631=\uFEAD=\uFEAE < \u0632=\uFEAF=\uFEB0 < \u0633=\uFEB1=\uFEB2=\uFEB4=\uFEB3 < \u0634=\uFEB5=\uFEB6=\uFEB8=\uFEB7 < \u0635=\uFEB9=\uFEBA=\uFEBC=\uFEBB < \u0636=\uFEBD=\uFEBE=\uFEC0=\uFEBF < \u0637=\uFEC1=\uFEC2=\uFEC4=\uFEC3 < \u0638=\uFEC5=\uFEC6=\uFEC8=\uFEC7 < \u0639=\uFEC9=\uFECA=\uFECC=\uFECB < \u063A=\uFECD=\uFECE=\uFED0=\uFECF < \u0641=\uFED1=\uFED2=\uFED4=\uFED3 < \u0642=\uFED5=\uFED6=\uFED8=\uFED7 < \u0643=\uFED9=\uFEDA=\uFEDC=\uFEDB < \u0644=\uFEDD=\uFEDE=\uFED0=\uFEDF < \u0645=\uFEE1=\uFEE2=\uFEE4=\uFEE3 < \u0646=\uFEE5=\uFEE6=\uFEE8=\uFEE7 < \u0647=\uFEE9=\uFEEA=\uFEEC=\uFEEB < \u0648=\uFEED=\uFEEE < \u064A=\uFEF1=\uFEF2=\uFEF4=\uFEF3 < \u0622=\uFE81=\uFE82 < \u0629=\uFE93=\uFE94 < \u0649=\uFEEF=\uFEF0 < \u0627";

阿拉伯字母可以采用四种形式,具体取决于它们在单词中的位置.因此,我在上面的规则字符串中所做的是使每个字母的所有4种形式相等.然后我指出用’

现在,如果我有一个星期几的集合(在这种情况下按星期几排序,而不是’按字母顺序’):

الأَحَد, الاِثنَين, الثُّلاثاء, الأَربِعاء, الخَميس, الجُمعة,السَّبت

我得到的结果根本没有排序:

الأَحَد, الخَميس, الاِثنَين, الثُّلاثاء, الأَربِعاء, السَّبت, الجُمعة

此外,对于如此少量的单词,需要相当长的时间才能使其无法使用.

有人知道我做错了什么,或者是否有一个救生库已经处理过这个问题?

在写这篇文章之前我做了一些谷歌搜索,我很惊讶我没有找到一个结果.

谢谢!

更新代码:

public static class TranslatableComparator implements java.util.Comparator {

@Override

public int compare(Translatable t1, Translatable t2) {

String sortingRules = "< \u0623=\uFE83=\uFE84 < \u0628=\uFE8F=\uFE90=\uFE92=\uFE91 < \u062A=\uFE95=\uFE96=\uFE98=\uFE97 < \u062B=\uFE99=\uFE9A=\uFE9C=\uFE9B < \u062C=\uFE9D=\uFE9E=\uFEA0=\uFE9F < \u062D=\uFEA1=\uFEA2=\uFEA4=\uFEA3 < \u062E=\uFEA5=\uFEA6=\uFEA8=\uFEA7 < \u062F=\uFEA9=\uFEAA < \u0630=\uFEAB=\uFEAC < \u0631=\uFEAD=\uFEAE < \u0632=\uFEAF=\uFEB0 < \u0633=\uFEB1=\uFEB2=\uFEB4=\uFEB3 < \u0634=\uFEB5=\uFEB6=\uFEB8=\uFEB7 < \u0635=\uFEB9=\uFEBA=\uFEBC=\uFEBB < \u0636=\uFEBD=\uFEBE=\uFEC0=\uFEBF < \u0637=\uFEC1=\uFEC2=\uFEC4=\uFEC3 < \u0638=\uFEC5=\uFEC6=\uFEC8=\uFEC7 < \u0639=\uFEC9=\uFECA=\uFECC=\uFECB < \u063A=\uFECD=\uFECE=\uFED0=\uFECF < \u0641=\uFED1=\uFED2=\uFED4=\uFED3 < \u0642=\uFED5=\uFED6=\uFED8=\uFED7 < \u0643=\uFED9=\uFEDA=\uFEDC=\uFEDB < \u0644=\uFEDD=\uFEDE=\uFED0=\uFEDF < \u0645=\uFEE1=\uFEE2=\uFEE4=\uFEE3 < \u0646=\uFEE5=\uFEE6=\uFEE8=\uFEE7 < \u0647=\uFEE9=\uFEEA=\uFEEC=\uFEEB < \u0648=\uFEED=\uFEEE < \u064A=\uFEF1=\uFEF2=\uFEF4=\uFEF3 < \u0622=\uFE81=\uFE82 < \u0629=\uFE93=\uFE94 < \u0649=\uFEEF=\uFEF0 < \u0627";

RuleBasedCollator col = null;

try {

col = new RuleBasedCollator(sortingRules);

} catch (ParseException e) {

//col = (RuleBasedCollator)RuleBasedCollator.getInstance(Locale.FRENCH);

}

return col.getCollationKey(t1.getTranslation().getText()).compareTo(col.getCollationKey(t2.getTranslation().getText()));

}

}

解决方法:

您无需定义自己的拼贴器,只需使用内置的拼贴器即可.然后你的比较器看起来像这样

public int compare(Translatable t1, Translatable t2) {

Collator.getInstance(new Locale("ar")).compare(t1.getTranslation().getText(), t2.getTranslation().getText());

}

(您可以通过浏览Collat​​or.getAvailableLocales()中的结果来检查collat​​or是否可用于阿拉伯语.)

如评论中所述,如果您担心性能,则应计算校对键,将它们存储在Translatable对象中,然后对它们进行排序.

如果您真的想知道您定义的内容与标准整理器之间的差异,请打印出规则:

System.out.println((RuleBasedCollator) Collator.getInstance(new Locale("ar"))).getRules();

标签:java,sorting,collation,arabic

来源: https://codeday.me/bug/20191006/1861369.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值