字符串排?/span>
本文是Sun官方以Blog形式发布的Java核心技术窍?JavaCoreTechTip)中的一个。我之前未xqjava.text.Collatorc,看过Sorting Stringsq个tip之后觉得有些意义Q故译在了此处Q也希望对其它朋友有所助益?2008.04.07最后更?
使用Javaq_q行字符串排序被认ؓ是一件简单的工作Q但为国际市场开发程序时Q则需要有更多的考虑。如果你陷入只关注英语的心态中Qƈ认ؓ你的E序会工作的很好Q因为它所昄的字W串从今往后都是一LQ你可能认ؓ一切都很正常。但一旦你有一位西班牙用户Q他希望能够正常地对mañanaq行排序Q但如果你都是用StringcM~省的compareҎd排序Q字W?#241;会跟在字符z之后Q而在正常的西班牙语排序中Q?#241;应该在字Wn和o之间。这是java.text包的cCollator发挥作用的地方了?
惛_q样的一l词
- first
- mañana
- man
- many
- maxi
- next
使用Stringcȝ默认排序机制Q即它的compare()ҎQ排序的l果会是:
- first
- man
- many
- maxi
- mañana
- next
此处Qmañana出现在maxi与next之间。而在西班牙语世界中,mañana应该出现在many和maxi之间Q?
因ؓ在字母表中,字符ñ(Meñe)跟在n之后。当来了一个d语用P想用他们自己的变音符Ӟ你就可以写一个自q定制排序规则来处?#241;Q?
否则一l用façade的设计模式将会怎样呢?你是否想让façade出现在factory之前或之后呢Q?关键是如同对c或其它字W那样去处理ç的小写变音符?
q就是类Collator能派上用场的地方了。类Collator用于对语a敏感的排序问题,q不会只Z它们的ASCII/Unicode字符d试排序?
使用Collator要求你在完全应用它的Ҏ之前要理解一个额外的属性,即称之ؓ强度(Strength)的属性。Collator的强度设|决定了在排序时如何使用?或弱)匚w?
该属性有4个可能的|PRIMARYQSECONDARYQTERTIARY和IDENTICAL。具体是哪个强度在生作用取决于语言环境?
典型圎ͼ会有如下的情c按从后往前的序QIDENTICAL强度表示能够被进行相同的处理的字W必L一致的。TERTIARY通常用于忽略大小写差异。SECONDARY用于忽略变音W,如n?#241;?
PRIMARY与IDENTICAL怼也是Z字母之间差异Q但是当处理控制字符和发xq是有所不同。查?code>Collator的javadocQ?
以获取更多关于这些强度之间的差异及分?Decomposition)模式规则的信息?
Z使用CollatorQ你需要先得到它的一个实例。你既可以调用getInstanceҎ以得C个针寚w认语a环境的Collator对象Q?
也可以传递一个指定的Locale对象lgetInstanceҎ以得C个针对特定语a环境的Collator对象。例如,Z获得针对一个西班牙语的
Collator对象Q你应用new Locale("es")dZ个西班牙语的Locale对象Q然后将它传入getInstanceҎ中:
Collator esCollator =
Collator.getInstance(new Locale("es"));
假设针对该语a环境的默认Collator强度Q针对西班牙语的默认强度是SECONDARY已经_了。然后你这个Collator对象如Q一Comparator对象
那样传入CollectionscȝsortҎ的比较规则参CQ以得到排序后的List对象?br />
Collections.sort(list, esCollator);
操作之前的单词列表,你现在就会得C个基于西班牙语字母表的恰当排序结果:
- first
- man
- many
- mañana
- maxi
- next
如果你在上述Collator中换用US的Locale对象Q由?#241;q不是US中本有的字母Q所以mañana会出现在man和many之间?
q儿有一个简z的例子以显C些差异?
import java.awt.*;
import java.text.*;
import java.util.*;
import java.util.List; // Explicit import required
import javax.swing.*;
public class Sort {
public static void main(String args[]) {
Runnable runner = new Runnable() {
public void run() {
String words[] = {"first", "mañana", "man",
"many", "maxi", "next"};
List list = Arrays.asList(words);
JFrame frame = new JFrame("Sorting");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
Box box = Box.createVerticalBox();
frame.setContentPane(box);
JLabel label = new JLabel("Word List:");
box.add(label);
JTextArea textArea = new JTextArea( list.toString());
box.add(textArea);
Collections.sort(list);
label = new JLabel("Sorted Word List:");
box.add(label);
textArea = new JTextArea(list.toString ());
box.add(textArea);
Collator esCollator = Collator.getInstance(new Locale("es"));
Collections.sort(list, esCollator);
label = new JLabel("Collated Word List:");
box.add(label);
textArea = new JTextArea(list.toString());
box.add(textArea);
frame.setSize(400, 200);
frame.setVisible(true);
}
};
EventQueue.invokeLater (runner);
}
}
最后还有一点儿关于语言排序规则的信息。通过调用getInstanceҎ而得到的Collator对象通常是支持特定语a的RuleBasedCollator实例?
你可使用RuleBasedCollatord义你自己的排序顺序。该cȝJavadoc更完整地描述了这U规则的语法Q但q是让我们先假设你有一?字符字母表,
q希望字母的序是CAFEQ而不是ACEFQ你的规则看h像q样Q?/span>
String rule =
"< c, C < a, A < f, F < e, E";
RuleBasedCollator collator = new RuleBasedCollator(rule);
上述规则通过展示不同字母的大写定义了特定的字母序为cafe。现在对单词列表aceQcafeQef和face使用新的规则q行排序Q?
排序l果的顺序ؓcafeQaceQface和efQ?string>
import java.text.*;
import java.util.*;
public class Rule {
public static void main(String args[]) throws ParseException {
String words[] = {"ace", "cafe", "ef", "face"};
String rule ="< c, C < a, A < f, F < e, E";
RuleBasedCollator collator = new RuleBasedCollator(rule);
List list = Arrays.asList(words);
Collections.sort(list, collator);
System.out.println(list);
}
}
在对上述代码~译q运行之后,你将看到使用新规则排序后的单词:
> javac Rule.java
> java Rule
[cafe, ace, face, ef]
请以后阅读Javadoc中更多的关于
规则语法的信息,再尝试扩展字母表q处理不同的变音W?br />
现在Q当你ؓ全世界开?
E序Ӟ你的E序p做出更好的准备以去适应本地用户了。也要确保字W串在资源包中,如之前的一个窍门所展示的那PEarlier tip?译注Q原文ƈ没有提供q个Earlier tip的正链接地址?

]]>