一般先得到一个Locale对象,然后,调用getInstance工厂方法来得到一个Collator对象。最后,当希望对字符串进行排序时,使用这个排序器的compare方法,而不是String类的compareTo方法。
Locale aLocale = new Locale("zh", "CN"); Collator collator = Collator.getInstance(aLocale); if(collator.compare("a", "b")<0){ System.out.PRintln(true); }最重要的是,Collator类实现了Comparator接口。因此,可以传一个排序器对象到Collections.sort方法中来对一组字符串进行排序 。排序强度
你可以设置排序器的强度来选择不同的排序行为。字符间的差别可以被分为首要的(primary)、 其次的(secondary)和再次的( tertiary)。比如,在英语中, “A”和“Z”之间的差别被归为首要的,而“A”和“Å”之间的差别是其次的, “A”和“a”之间是再次的。如果将排序器的强度设置成Collator.PRIMARY,那么排序器将只关注primary级的差别。如果设置成Collator.SECONDARY,排序器将把secondary级的差别也考虑进去。就是说,两个字符串在“secondary”或“tertiary”强度下更容易被区分开来,如表5-4所示。如果强度被设置为Collator.IDENTICAL,则不允许有任何差异。这种设置在与排序器的第二种相当技术性的设置,即分解模式(decomposition mode),联合使用时,就会显得非常有用。
分解
Unicode标准对字符串定义了四种范化形式(normalization form):D、KD、C和KC 。这其中的两种都是用于排序的。在范化形式D中,重音字符被分解为基字符和组合重音符。例如,Å就被转换成由字母A和上方组合环°构成的序列。范化形式KD更近一步地将兼容性字符(compatibility character)也进行了分解,例如ffi连字或商标符号TM 。
我们可以选择排序器所使用的范化程度:Collator.NO_DECOMPOSITION表示不对字符串做任何范化,这个选项处理速度较快,但是对于以多种形式表示字符的文本就显得不适用了;默认值Collator.CANONICAL_DECOMPOSITION使用范化形式D,这对于包含重音但不包含连字的文本是非常有用的形式;最后是使用范化形式KD的“完全分解”。
让排序器去多次分解一个字符串是很浪费的。如果一个字符串要和其他字符串进行多次比较,可以 将 分 解 的 结 果 保 存 在 一 个 排 序 键 对 象 中 。getCollationKey方法返回一个CollationKey对象,可以用它来进行更深入的、更快速的比较操作。
Collator collator = Collator.getInstance(aLocale); String aString =""; CollationKey cKey = collator.getCollationKey(aString); if(cKey.compareTo(collator.getCollationKey(new String("")))==0){ } 最后,有可能在你不需要进行排序时,也希望将字符串转换成它们的范化形式。例如,在将字符串存储到数据库中,或与其他程序进行通信时。从java SE 6.0开始,java.text.Normalizer类实现了对范化的处理。 String aString ="Åöcvsz"; String bString = Normalizer.normalize(aString, Normalizer.Form.NFKD);Collatorstatic Locale[] getAvailableLocales()返回Locale对象的一个数组,通过它可以得到Collator对象。static Collator getInstance()static Collator getInstance(Locale l)为默认或给定的locale返回一个排序器。int compare(String a, String b)如果a在b之前,则返回负值;如果它们等价,则返回0,否则返回正值。boolean equals(String a, String b)如果它们等价,则返回true,否则返回false。void setStrength(int strength)int getStrength()设置或获取排序器的强度。更强的排序器可以区分更多的词。强度的值可以是Collator.PRIMARY、 Collator.SECONDARY和Collator.TERTIARY。void setDecomposition(int decomp)int getDecompositon()设置或获取排序器的分解模式。分解越细,判断两个字符串是否相等时就越严格。分解的等级值可以是Collator.NO_DECOMPOSITION、 Collator.CANONICAL_DECOMPOSITION和Collator.FULL_DECOMPOSITION。CollationKey getCollationKey(String a)返回一个排序器键,这个键包含一个按特定格式分解的字符,可以快速地和其他排序器键进行比较。CollationKeyint compareTo(CollationKey b)如果这个键在b之前,则返回一个负值;如果两者等价,则返回0,否则返回正值。Normalizerstatic String normalizer(CharSequence str, Normalizer.Form form)返回str的范化形式, form的值是ND、 NKD、 NC或NKC之一。消息格式化Java类库中有一个MessageFormat类,用来格式化带变量的文本 。"dsadsadas{2}fsfa{1}fsd{0}" 括号中的数字是一个占位符 ,可以用实际的名字和值来替换它 。使用静态方法MessageFormat.format可以用实际的值来替换这些占位符。从JDK 5.0开始,它已经是一个“varargs”方法了,所以你可以通过下面的方法提供参数 String string = MessageFormat.format("ewqe=={2}==as{0}==={1}", "aaa","bbbb","ccc"); System.out.println(string);//ewqe==ccc==asaaa===bbbb一般来说,占位符标记后面可以跟一个类型(type)和一个风格(style),它们之间用逗号隔开。 类型可以是 number,time,date,choice。如果类型是number,那么风格可以是integer、currency、percent。或者可以是数字格式模式,就像$、##0。如果类型是time或date,那么风格可以是 short、medium、long、full。或者一个日期格式模版像yyyy-MM-dd。 静态的MessageFormat.format方法使用当前的locale对值进行格式化。要想用任意的locale进行格式化,还有一些工作要做,因为这个类还没有提供任何可以使用的“varargs”方法。你需要把将要格式化的值置于Object[]数组中,就像下面这样
MessageFormat mf = new MessageFormat("{3}==={2}000{1}---{0}",new Locale("zh","CN")); String result = mf.format(new Object[]{"aaa","bbb","ccc","ddd"}); System.out.println(result);//ddd===ccc000bbb---aaaMessageFormatMessageFormat(String pattern)MessageFormat(String pattern, Locale loc)用给定的模式和locale构建一个消息格式对象。void applyPattern(String pattern)给消息格式对象设置特定的模式。void setLocale(Locale loc)Locale getLocale()设置或获取消息中占位符所使用的locale。这个locale仅仅被通过调用applyPattern方法所设置的后续模式所使用。static String format(String pattern, Object... args)通过使用args[i]作为站位符{i}的输入来格式化pattern字符串。StringBuffer format(Object args, StringBuffer result, FieldPosition pos)格式化MessageFormat的模式。 args参数必须是一个对象数组。被格式化的字符串会被附加到result末尾,并返回result。如果pos等于newFieldPosition(MessageFormat.Field.ARGUMENT),就用它的beginIndex和endIndex属性值来设置替换占位符{1}的文本位置。如果不关心位置信息,可以将它设为null。一个选择格式是由一个序列对,每一个对包括一个下限(lower limit)一个格式字符串(format string)。double[] limit = {0, 1};String[] format = {"Hello0", "Hello1{1}"};ChoiceFormat cf = new ChoiceFormat(limit, format);MessageFormat mf = new MessageFormat("{0}");mf.setFormatByArgumentIndex(0, cf);for (int i = 0; i < 2; ++i){ System.out.println(mf.format(new Object[]{new Integer(i), new Integer(i+1)}));}//Hello0/nHello12文本文件和字符集 当把数据保存到一个文本文件中时,应该照顾到本地的字符编码,这样程序的用户就可以用他们的其他程序打开这个文本文件。字符编码是在FileWriter的构造器中指定的 。
FileWriter fw = new FileWriter(xxx,"UTF-8");源文件的字符编码源文件:本地编码类文件:modified UTF-8虚拟机:UTF-16 。为了使你的源文件能够到处使用,必须使用通用的ASCII编码。就是说,你需要将所有非A S C I I字符转换成等价的Unicode编码。 定位资源包
需要对这些包使用一种统一的命名规则。例如,为德国定义的资源放在一个名为“包名_de_DE”的文件中,为所有说德语的国家所共享的资源放在名为“ 包名_de”的文件中。一般来说,使用包名_语言_国家来命名所有和国家相关的资源,使用包名_语言来命名所有和语言相关的资源。最后,作为后备,可以把默认资源放到一个没有后缀的文件中。可以用下面的命令加载一个包
ResourceBundle rb = ResourceBundle.getBundle(bundleName,currentLocale);getBundle方法试图加载符合当前locale定义的语言、国家和变量的包。如果失败,通过依次放弃语言、变量和国家来继续进行查找。同样的查找被应用于默认的locale,最后,如果还不行的话就去查看默认的包文件,如果这也失败了,方法抛出一个MissingResourceException异常。这就是说, getBundle方法试图加载以下的包。包名_当前Locale的语言_当前Locale的国家_当前Locale的变量包名_当前Locale的语言_当前Locale的国家包名_当前Locale的语言包名_默认Locale的语言_默认Locale的国家_默认Locale的变量包名_默认Locale的语言_默认Locale的国家包名_默认Locale的语言包名 一旦getBundle方法定位了一个包,比如, 包名_de_DE,它还会继续查找包名_de和包名。如果这些包也存在,它们在资源层次中就成为了包名_de_DE的父包。以后,当查找一个资源时,如果在当前包中没有找到,就去查找其父包。就是说,如果一个特定的资源在当前包中没有被找到。比如,某个特定资源在包名_de_DE中没有找到,那么就会去查询包名_de和包名。 属性文件 对字符串进行国际化是很直接的。你把所有字符串放到一个属性文件中,比如abc.properties。这是一个每行存放一个键-值对的文本文件。命名你的属性文件 abc.properties,abc_zh.properties等要查找一个特定的字符串,可以调用
String a = bundle.getString("name");存储属性的文件都是ASCII文件。包类为了提供字符串以外的资源,需要定义类,它扩展自ResourceBundle类。应该使用标准的命名规则来命名你的类,
abc.java,abc_zh.java当搜索包时,如果在类中的包和在属性文件中的包中都存在匹配,优先选择类中的包。实现资源绑定类的最简单方法就是继承ListResourceBundle类。ListResourceBundle让你把所有资源都放到一个对象数组并提供查找功能。
public class abc_zh extends ListResourceBundle{ public Object[] getContents(){ return contents; } public static final Object[] contents={ {"name","xiaoming"}, {"age",12} }}或者,你的资源绑定类可以扩展ResourceBundle类。然后需要实现两个方法,一是列出所有键,二是用给定的键查找相应的值Enumeration<String> getKeys();Object handleGetObject(String key);ResourceBundlestatic ResourceBundle getBundle(String baseName, Locale loc)static ResourceBundle getBundle(String baseName)在给定的locale或默认的locale下以给定的名字加载资源绑定类和它的父类。如果资源包类位于一个Java包中,那么类的名字必须包含完整的包名,例如“ intl.ProgramResources”。资源包类必须是public的,这样getBundle方法才能访问它们。Object getObject(String name)从资源包或它的父包中查找一个对象。String getString(String name)从资源包或它的父包中查找一个对象并把它转型成字符串。String[] getStringArray(String name)从资源包或它的父包中查找一个对象并把它转型成字符串数组。Enumeration<String> getKeys()返回一个枚举对象,枚举出资源包中的所有键,也包括父包中的键。Object handleGetObject(String key)如果你定义了自己的资源查找机制,这个方法需要被覆写,用来查找与给定的键相关联的资源的值。
新闻热点
疑难解答