Java提供给我们软件国际化的解决方案,这些国际化API基于Unicode标准,并且包括文本、(货币)数字、日期以及用户自定义对象的适配,从而使得软件能够应用到任何国家或地区。国际化英文为“Internationalization”,通常简写成i18n(实际开发经常使用简写)。更多有关Java国际化的内容可以参考Oracle的相关网站。

文字国际化

Java语言基于Unicode字符集。Unicode是一种国际字符集标准,支持世界上所有主要文字以及常见技术符号。早期Unicode规定所有字符固定16bit宽(也就是UCS-2),但是Unicode标准中的字符早已超过16bit所能表示的范围,现规定的代码点范围在U+0000到U+10FFFF之间。Java标准使用的UTF-16定义的编码方式允许使用一个或两个16bit单位来表示所有的Unicode代码点。

Java基本数据类型char是一个无符号的16bit整数,可以表示U+0000到U+FFFF范围内的码点(BMP平面字符),同时也可作为UTF-16的码元,即32bit编码中的一半(两个char拼成一个字的辅助平面字符,但这种字符使用频率很低)。

更多有关字符编码的知识可以参考我的这篇文章

Java平台中表示字符序列的各种类型如:char[]、java.lang.CharSequence的实现类(如String类)以及java.text.CharacterIterator的实现类都是UTF-16序列。大多数Java源代码是使用ASCII(一种7bit字符编码方式)或ISO-8859-1(西欧8bit字符编码)或GBK(中国国标扩展编码)所编写的,但在处理之前都被转换为UTF-16编码。

Character类作为基本数据类型char的包装类,里面有很多确定字符属性的静态方法,如isLowerCaseisTitleCaseisDigit等,在Java5之前这些方法只有char作为参数,所以只接受U+0000到U+FFFF范围内的码点,Java5之后这些方法有了int类型作为参数的重载方法,这样就能表示所有Unicode代码点。

区域识别与本地化

1. Locale—地区性

Java平台将语言和地区分开定义,但均使用Locale类表示,Locale类通常代表特定地理位置,政权或文化区域。国际化的API中都有重载的方法要求提供一个Locale类的实例,而Locale类中有许多的静态常量用于表示常见的国家和地区的本地化对象。比如:Local.CHINA,Local.CANADA,Local.JAPEN

官网有Java支持的所有国家或地区语言的列表

2. ResourceBundle—国际化资源

通常我们的应用或系统不会将字符(串)等信息硬编码编译到Java字节码中,而是将这些信息以资源文件的形式存储在磁盘中,这是我们通常需要ResourceBundle这个类。

ResourceBundle是一个抽象类,代表着程序中所使用资源集合(字符串或图片路径等)。将资源和Java类一起打包,可以利用Java类加载机制来查找资源,ResourceBundle中包含特定区域的资源对象,当一个程序需要该区域的资源,程序可以从资源包中加载它,这样开发人员编写代码,可以不用关注特定区域的资源问题(资源文件可以单独维护)。

Java平台资源文件主要是properties格式

ResourceBundle中有几个重载的静态方法getBundle可以用来根据资源名(不包括区域信息的基本名称)来获取ResourceBundle对象,有ResourceBundle对象后即可通过getStringgetObject等方法传入Key即可获取对应的Value。

示例:

比如你有两个特定区域的资源:MyResource_en.propertiesMyResource_zh.properties

# properties文件内容
key=value
  • 1
  • 2

java代码获取资源文件内容

java 
// Java会根据当前系统默认区域获取对应资源,如果没有则使用无区域信息的默认资源 
ResourceBundle res = ResourceBundle.getBundle("MyResource"); 
// 通过key-value的方式取得资源内的信息 
String value = res.getString("key"); 

ResourceBundle的子类

ResourceBundle有两个子类:ListResourceBundle和PropertyResourceBundle。

1、ListResourceBundle是一个抽象类,需要我们继承并实现Object[][] getContents()方法:

// 默认 (美国英语)public class MyResources extends ResourceBundle {public Object handleGetObject(String key) {if (key.equals("okKey")) return "Ok";if (key.equals("cancelKey")) return "Cancel";return null;}public Enumeration<String> getKeys() {return Collections.enumeration(keySet());}// 重写handleKeySet方法并在getKeys方法中调用keySet方法// keySet可以获取handleKeySet的返回值protected Set<String> handleKeySet() {return new HashSet<String>(Arrays.asList("okKey", "cancelKey"));}}// 中文public class MyResources_zh extends MyResources {public Object handleGetObject(String key) {// 对于不需要重写的内容可以从父类中获取if (key.equals("cancelKey")) return "取消";return null;}protected Set<String> handleKeySet() {return new HashSet<String>(Arrays.asList("cancelKey"));}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

可以看出JDK的sun包中有很多这种方式书写的资源:

2、PropertyResourceBundle就是ResourceBundle通过get方法获取资源的形式,它使用的是Properties工具类获取.properties文件中的信息。

日期与时间的处理

java.util.Date类代表着毫秒精度的日期时间,该类有几个方法可以获取日期中的年、月、日、时、分、秒等信息。但是由于该类依赖于时区,与国际化不兼容,大部分方法已经被弃用,通常我们使用Calendar类来转换日期和时间,并通过DateFormat类来格式化或解析日期时间字符串。

Calendar

Calendar是一个抽象类,它用于一个整数的计算机纪元点时间转换成年、月、日、星期等信息。GregorianCalendar类是Calendar实现类,它根据格林尼治时间历法(公历)来实现。同时Calendar类提供了getInstance静态工厂方法来创建Calendar实例对象。

TimeZone

TimeZone是一个抽象类,封装了一个相对于GMT(格林尼治标准时间)的偏移值。TimeZone.getTimeZone工厂方法能通过指定zoneID来创建一个TimeZone实例对象。另外TimeZone还有一个SimpleTimeZone实现类可以创建TimeZone对象。

Calendar类及其子类会使用TimeZone进行本地时间与UTC(通用标准时间)之间的转换。

格式化

i18n中重要的一个部分就是文本格式化,这些功能主要在java.text包中:

主要分为三类:

  • DateFormat:日期格式化。根据区域不同使用不同的日期格式,可以自定义日期显示的格式。
  • MessageFormat:信息格式化。根据区域不同使用不同语言的字符显示信息,比如谷歌的网站对于不同的国家会以不同的语言显示网页信息。
  • NumberFormat:数字格式化。根据不同区域使用不同的数字格式,比如货币显示,西方国家会每隔三位加一个空格或逗号。

Format类主要有两个抽象方法需要子类去实现:

  • format方法用于将对象格式化成字符串。
  • parseObject方法用于将字符串按格式解析成对象。

DateFormat和NumberFormat这两个是抽象类,它们都有静态工厂方法getXxxInstance来获取该类的实例对象,同时它们也提供了子类可以实例化。

日期时间格式化

DateFormat

DateFormat有几个静态工厂方法getXxxInstance,DateFormat提供了几个标准的时间格式:

    /*** Constant for full style pattern.*/public static final int FULL = 0;/*** Constant for long style pattern.*/public static final int LONG = 1;/*** Constant for medium style pattern.*/public static final int MEDIUM = 2;/*** Constant for short style pattern.*/public static final int SHORT = 3;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

默认时期格式为:

    /*** Constant for default style pattern.  Its value is MEDIUM.*/public static final int DEFAULT = MEDIUM;
  • 1
  • 2
  • 3
  • 4

通过getXxxInstance方法可以传入这些常量设置日期或时间的格式,这几个getXxxInstance方法最终都辗转调用下面这个方法:

private static DateFormat get(int timeStyle, int dateStyle, int flags, Locale loc)
  • 1

其中timeStyle代表时间的显示格式(时分秒部分),dateStyle代表日期的显示格式(年月日部分),这两个参数就是上面四个常量;flags参数有三种状态:1表示值显示时间部分,2表示只显示日期部分,3表示日期时间都显示;loc参数用于指定国家和地区,从而应对不同国家的时间格式。

DateFormat底层使用Calendar和TimeZone(Calendar内部)来解析时间,可以通过这两个属性的getter/setter方法来设置日期和时区。

有了DateFormat对象并设置了日期时间后即可调用它的format(格式化日期)或parse(解析日期)方法。

        DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG,Locale.CHINA);String timeString = df.format(System.currentTimeMillis());System.out.println(timeString);Date parse = df.parse(timeString);System.out.println(parse);System.out.println(parse.getTime());
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

输出结果:

2017年8月4日 上午11时04分31秒
Fri Aug 04 11:04:31 CST 2017
1501815871000
  • 1
  • 2
  • 3

SimpleDateFormat

SimpleDateFormat是DateFormat的子类,可以由开发者自己定义解析格式。

示例:

        SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");String timeStr1 = df.format(System.currentTimeMillis());System.out.println(timeStr1);df.applyPattern("yyyy年MM月dd日-HH时mm分ss秒S毫秒");String timeStr2 = df.format(System.currentTimeMillis());System.out.println(timeStr2);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

输出结果:

2017/08/04 11:03:23
2017年08月04日-11时03分23秒119毫秒
  • 1
  • 2

官方API文档中给出了SimpleDateFormat的各种pattern的规则。

数字格式化

NumberFormat

NumberFormat和DateFormat类似,也提供了几个标准的数字格式:

    private static final int NUMBERSTYLE = 0;      // 默认数字风格private static final int CURRENCYSTYLE = 1;    // 货币风格private static final int PERCENTSTYLE = 2;     // 百分比风格private static final int SCIENTIFICSTYLE = 3;  // 科学计数风格private static final int INTEGERSTYLE = 4;     // 整数风格
  • 1
  • 2
  • 3
  • 4
  • 5

我们不需要指定数字格式,NumberFormat已经为我们封装了这几个风格样式并提供给我们静态方法:

public final static NumberFormat getInstance();                        // NUMBERSTYLE
public final static NumberFormat getInstance(Locale inLocale);         // NUMBERSTYLE
public final static NumberFormat getNumberInstance();                  // NUMBERSTYLE
public final static NumberFormat getNumberInstance(Locale inLocale);   // NUMBERSTYLE
public final static NumberFormat getIntegerInstance();                 // INTEGERSTYLE
public final static NumberFormat getIntegerInstance(Locale inLocale);  // INTEGERSTYLE
public final static NumberFormat getCurrencyInstance();                // CURRENCYSTYLE
public final static NumberFormat getCurrencyInstance(Locale inLocale); // CURRENCYSTYLE
public final static NumberFormat getPercentInstance();                 // PERCENTSTYLE
public final static NumberFormat getPercentInstance(Locale inLocale);  // PERCENTSTYLE
/*public*/ final static NumberFormat getScientificInstance();          // SCIENTIFICSTYLE
/*public*/ static NumberFormat getScientificInstance(Locale inLocale); // SCIENTIFICSTYLE
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

示例:

        NumberFormat[] formats = {NumberFormat.getInstance(),NumberFormat.getNumberInstance(),NumberFormat.getIntegerInstance(),NumberFormat.getCurrencyInstance(),NumberFormat.getPercentInstance()};for (int i = 0; i < formats.length; i++) {System.out.println(formats[i].format(100L));System.out.println(formats[i].format(123.456F));}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

输出结果:

100
123.456
100
123.456
100
123
¥100.00
¥123.46
10,000%
12,346%
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

DecimalFormat

该类允许我们自定义十进制数字的格式化。

示例:

        DecimalFormat format;format = new DecimalFormat("####,####,###0.0# 圆整");System.out.println(format.format(12345678.90F));System.out.println(format.format(-12345678.90F));format.applyPattern("0.0#####E0####");System.out.println(format.format(1234567894987654321.90F));System.out.println(format.format(12.34F));format.applyPattern("00.0#E0##");System.out.println(format.format(1234567894987654321.90F));System.out.println(format.format(12.34F));
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

运行结果:

1234,5679.0 圆整
-1234,5679.0 圆整
1.2345679396E18
1.2340000153E1
12.3457E17
12.34E0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

信息格式化

所谓“信息”格式化,其实就是字符串格式化,可以通过MessageFormat这个类构造一个字符串显示给终端用户。不过在这之前要说说JDK1.0开始就已经存在的老牌API——java.util.Formatter

java.util.Formatter

我们知道String类中有一个静态方法String.format(String format, Object... args)和C语言中的sprintf函数极为相似,这个方法底层就是用了java.util.Formatter类来实现,而待会儿要讲的MessageFormat类功能远比这个类功能强大(指的是格式化字符串这方面),所以在这之前我们先来说说java.util.Formatter这个类。

我们知道C语言中有几个I/O流的函数:printfsprintffprintf(在C11标准中还提供了这几个方法的安全版本,防止溢出)。

java.util.Formatter类能实现类似于C语言中的这几个函数,只需要在构造方法中传入不同的输出流即可,下面列一个表把C语言中的函数与Java中的Formatter类的应用进行对比:

C语言函数 Java API 备注
printf(const char *format, ...) System.out.format(String format, Object ... args) System.out是一个PrintStream对象,该对象底层使用java.util.Formatter对象进行格式化输出。
sprintf( char *buffer, const char *format, ... ) String.format(String format, Object... args) String.format方法每次调用都会new一个Formatter对象。
fprintf( FILE *stream, const char *format, ... ) new Formatter(new File(filename)).format(String format, Object ... args) Formatter类可以直接封装输出流,你可以直接传入一个文件名或文件对象。

但是由于Java是面向对象的语言,format参数是Object类型,所以如果我们想要格式化输出自定义对象,则该对象必须实现java.util.Formattable接口,但实际上JDK中没有任何类实现了该接口,这样做还不如重载Object.toString方法。另外由于java中String是不可变的对象,所以String.format方法并没有像sprintf函数一样灵活性。

而相反MessageFormat类中有一个方法:

public final StringBuffer format(Object[] arguments, StringBuffer result, FieldPosition pos);
  • 1

这个方法使用的是StringBuffer类作为存储字符串的缓冲区,这才契合了sprintf的功能。

java.text.MessageFormat

前面扯到C语言和Java API中格式化输出的对比,接下来就继续谈谈MessageFormat的强大功能。

MessageFormat融合了前面讲到的DateFormat,NumberFormat的功能,我们可以直接通过new关键字创建MessageFormat的对象。MessageFormat有以下两个构造方法:

public MessageFormat(String pattern);
public MessageFormat(String pattern, Locale locale);
  • 1
  • 2

MessgaeFormat类还提供了一个静态方法,如果MessageFormat使用较多不建议使用这个静态方法,因为该方法要创建MessageFormat对象:

    public static String format(String pattern, Object ... arguments) {MessageFormat temp = new MessageFormat(pattern);return temp.format(arguments);}
  • 1
  • 2
  • 3
  • 4

构造方法中需要传递一个pattern参数,MessageFormat的pattern语法如下:

MessageFormatPattern:StringMessageFormatPattern FormatElement StringFormatElement:{ ArgumentIndex }{ ArgumentIndex , FormatType }{ ArgumentIndex , FormatType , FormatStyle }FormatType: one ofnumber | date | time | choiceFormatStyle:shortmediumlongfullintegercurrencypercentSubformatPattern
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

先来看一个例子:

        int place = 7;String event = "一场战斗";String result = MessageFormat.format("在 {1,date} 的 {1,time} , 在第{0,number,integer}区发生了{2}。", place,new Date(), event);System.out.println(result);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

运行结果:

在 2017-8-4 的 21:37:37 , 在第7区发生了一场战斗。
  • 1

在模式字符串中我们可以插入{ ArgumentIndex , [FormatType , [FormatStyle]] }这样的语法作为占位符,可以在后面的变长参数中填充这些占位符。

占位符语法中有三个参数:

  • ArgumentIndex:变长参数的索引,从0开始。

  • FormatTypeFormatStyle来自于NumberFormat和DateFormat以及它们的子类:

FormatType FormatStyle Subformat Created
(none) (none) null
number (none) NumberFormat.getInstance(getLocale())
integer NumberFormat.getIntegerInstance(getLocale())
currency NumberFormat.getCurrencyInstance(getLocale())
percent NumberFormat.getPercentInstance(getLocale())
SubformatPattern newDecimalFormat(subformatPattern,DecimalFormatSymbols.getInstance(getLocale()))
date (none) DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale())
short DateFormat.getDateInstance(DateFormat.SHORT, getLocale())
medium DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale())
long DateFormat.getDateInstance(DateFormat.LONG, getLocale())
full DateFormat.getDateInstance(DateFormat.FULL, getLocale())
SubformatPattern newSimpleDateFormat(subformatPattern, getLocale())
time (none) DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale())
short DateFormat.getTimeInstance(DateFormat.SHORT, getLocale())
medium DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale())
long DateFormat.getTimeInstance(DateFormat.LONG, getLocale())
full DateFormat.getTimeInstance(DateFormat.FULL, getLocale())
SubformatPattern newSimpleDateFormat(subformatPattern, getLocale())
choice SubformatPattern newChoiceFormat(subformatPattern)

有了这张表,就知道FormatType 与前面的NumberFormat和DateFormat之间的关系了。

继续看两个例子:

1、对磁盘空间的使用情况进行格式化处理

        Object[][] testArgs = {{ 0, "MyDisk" },{ 1, "MyDisk" },{ 1234, "MyDisk" }};MessageFormat form = new MessageFormat("The disk \"{1}\" contains {0} file(s).");for (int i = 0; i < testArgs.length; i++) {System.out.println(form.format(testArgs[i]));}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

输出结果:

The disk "MyDisk" contains 0 file(s).
The disk "MyDisk" contains 1 file(s).
The disk "MyDisk" contains 1,234 file(s).
  • 1
  • 2
  • 3

2、对与磁盘中文件数为0的情况,显示no file,对于文件数为1的情况,显示one file

        Object[][] testArgs = {{ 0, "MyDisk" },{ 1, "MyDisk" },{ 1234, "MyDisk" }};MessageFormat form = new MessageFormat("The disk \"{1}\" contains {0}.");double[] filelimits = { 0, 1, 2 };String[] filepart = { "no files", "one file", "{0,number} files" };ChoiceFormat fileform = new ChoiceFormat(filelimits, filepart);form.setFormatByArgumentIndex(0, fileform);for (int i = 0; i < testArgs.length; i++) {System.out.println(form.format(testArgs[i]));}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

输出结果:

The disk "MyDisk" contains no files.
The disk "MyDisk" contains one file.
The disk "MyDisk" contains 1,234 files.
  • 1
  • 2
  • 3

ChoiceFormat是一个选区格式化(可以理解为分支语句),使用它我们可以在pattern模式串中写分支语句(有点类似于正则表达式中的条件分支),比如上面的需求我们可以这样实现:

        Object[][] testArgs = {{ 0, "MyDisk" },{ 1, "MyDisk" },{ 1234, "MyDisk" }};MessageFormat form = new MessageFormat("The disk \"{1}\" contains {0, choice, 0#no files|1#one file|1<{0,number,integer} files}.");for (int i = 0; i < testArgs.length; i++) {System.out.println(form.format(testArgs[i]));}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

更多有关ChoiceFormat的信息可以参考官方文档

字符串操作

字符串比较

String类实现了Comparable接口所以提供了一个compareTo方法,但是该方法是直接比较字符的Unicode编码值:

    public int compareTo(String anotherString) {int len1 = value.length;int len2 = anotherString.value.length;int lim = Math.min(len1, len2);char v1[] = value;char v2[] = anotherString.value;int k = 0;while (k < lim) {char c1 = v1[k];char c2 = v2[k];if (c1 != c2) {return c1 - c2;}k++;}return len1 - len2;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

但是Unicode中文字符并没有严格的排序(有一说是按笔画排序,但在Unicode官网下的编码表中看并没有严格按笔画排序),而且我们通常习惯按照中文拼音对中文字符串进行排序。Java已经给我们提供了相应的解决方案。

Collator

Collator类能按照相应国家和区域的习惯进行字符串比较,我们可以使用它来对字符(串)进行排序。

Collator类是一个抽象类,其子类实现了特定的比较策略,目前Java平台提供了一个子类RuleBasedCollator,能适用于广泛的语言。当然我们可以继续创建它的子类来适应我们其他独特的需求。

示例:

    public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("林志炫");list.add("杨洋");list.add("刘亦菲");list.add("邓紫棋");list.add("赵丽颖");list.add("周杰伦");list.add("邓超");list.add("孙俪");list.add("刘诗诗");list.add("杨宗纬");list.add("林志颖");list.sort(null);System.out.println("String默认排序:");printList(list);list.sort(new Comparator<String>() {Collator collator = Collator.getInstance(Locale.CHINESE);@Overridepublic int compare(String o1, String o2) {return collator.compare(o1, o2);}});System.out.println();System.out.println("Collator排序:");printList(list);}public static void printList(List<String> list) {list.forEach(new Consumer<String>() {@Overridepublic void accept(String t) {System.out.print(t + " ");}});}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

输出结果:

String默认排序:
刘亦菲 刘诗诗 周杰伦 孙俪 杨宗纬 杨洋 林志炫 林志颖 赵丽颖 邓紫棋 邓超
Collator排序:
邓超 邓紫棋 林志颖 林志炫 刘诗诗 刘亦菲 孙俪 杨洋 杨宗纬 赵丽颖 周杰伦
  • 1
  • 2
  • 3
  • 4

虽然Collator能完成基本的字符排序,但如果相对繁体等不常用的字进行排序,这个方法就不行了。

        list.add("林志炫");list.add("杨洋");list.add("楊洋");list.add("刘亦菲");list.add("劉亦菲");list.add("邓紫棋");list.add("鄧紫棋");list.add("赵丽颖");list.add("趙麗穎");list.add("周杰伦");list.add("周杰倫");list.add("邓超");list.add("鄧超");list.add("孙俪");list.add("孫儷");list.add("刘诗诗");list.add("劉詩詩");list.add("杨宗纬");list.add("楊宗緯");list.add("林志颖");
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

输出结果:

String默认排序:
刘亦菲 刘诗诗 劉亦菲 劉詩詩 周杰伦 周杰倫 孙俪 孫儷 杨宗纬 杨洋 林志炫 林志颖 楊宗緯 楊洋 赵丽颖 趙麗穎 邓紫棋 邓超 鄧紫棋 鄧超
Collator排序:
邓超 邓紫棋 林志颖 林志炫 刘诗诗 刘亦菲 孙俪 杨洋 杨宗纬 赵丽颖 周杰伦 周杰倫 劉亦菲 劉詩詩 孫儷 楊洋 楊宗緯 趙麗穎 鄧超 鄧紫棋
  • 1
  • 2
  • 3
  • 4

关于中文排序的问题,这里有一篇文章给出了几个解决方案

字符串迭代

java.text.StringCharacterIterator类封装好了字符串迭代功能,这个类很鸡肋,和普通的for循环迭代没啥区别。

StringCharacterIterator是CharcterIterator接口的实现类,CharcterIterator接口中定义了Unicode字符双向迭代的规则。

示例:

 // 正向迭代public void traverseForward(CharacterIterator iter) {for(char c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) {processChar(c);}}// 反向迭代public void traverseBackward(CharacterIterator iter) {for(char c = iter.last(); c != CharacterIterator.DONE; c = iter.previous()) {processChar(c);}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

编码转换

Java使用Unicode作为编码方法,经常会出现将将程序中的数据输出到外部(磁盘文件或网络响应等),最常用的两个类就是InputStreamReader和OutputStreamWriter,这两个类后期也是用Charset类来实现核心功能的。Charset采用spi设计模式,允许我们开发自定义的编解码器。

Charset

写个例子看一下Charset支持哪些编码:

    public static void main(String[] args) {SortedMap<String, Charset> charsets = Charset.availableCharsets();for (String name : charsets.keySet()) {System.out.print("Name:");System.out.print(name);Charset charset = charsets.get(name);System.out.print("  ");System.out.print("DisplayName:");System.out.print(charset.displayName());System.out.print("  ");System.out.print("Aliases:");Set<String> aliases = charset.aliases();for (String alias : aliases) {System.out.print(alias);System.out.print(" ");}System.out.println();}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

输出结果:

Name:Big5  DisplayName:Big5  Aliases:csBig5
Name:Big5-HKSCS  DisplayName:Big5-HKSCS  Aliases:big5-hkscs big5hk Big5_HKSCS big5hkscs
Name:CESU-8  DisplayName:CESU-8  Aliases:CESU8 csCESU-8
Name:EUC-JP  DisplayName:EUC-JP  Aliases:csEUCPkdFmtjapanese x-euc-jp eucjis Extended_UNIX_Code_Packed_Format_for_Japanese euc_jp eucjp x-eucjp
Name:EUC-KR  DisplayName:EUC-KR  Aliases:ksc5601-1987 csEUCKR ksc5601_1987 ksc5601 5601 euc_kr ksc_5601 ks_c_5601-1987 euckr
Name:GB18030  DisplayName:GB18030  Aliases:gb18030-2000
Name:GB2312  DisplayName:GB2312  Aliases:gb2312 euc-cn x-EUC-CN euccn EUC_CN gb2312-80 gb2312-1980
Name:GBK  DisplayName:GBK  Aliases:CP936 windows-936
Name:IBM-Thai  DisplayName:IBM-Thai  Aliases:ibm-838 ibm838 838 cp838
Name:IBM00858  DisplayName:IBM00858  Aliases:cp858 858 PC-Multilingual-850+euro cp00858 ccsid00858
Name:IBM01140  DisplayName:IBM01140  Aliases:cp1140 1140 cp01140 ebcdic-us-037+euro ccsid01140
Name:IBM01141  DisplayName:IBM01141  Aliases:1141 cp1141 cp01141 ccsid01141 ebcdic-de-273+euro
Name:IBM01142  DisplayName:IBM01142  Aliases:1142 cp1142 cp01142 ccsid01142 ebcdic-no-277+euro ebcdic-dk-277+euro
Name:IBM01143  DisplayName:IBM01143  Aliases:1143 cp01143 ccsid01143 cp1143 ebcdic-fi-278+euro ebcdic-se-278+euro
Name:IBM01144  DisplayName:IBM01144  Aliases:cp01144 ccsid01144 ebcdic-it-280+euro cp1144 1144
Name:IBM01145  DisplayName:IBM01145  Aliases:ccsid01145 ebcdic-es-284+euro 1145 cp1145 cp01145
Name:IBM01146  DisplayName:IBM01146  Aliases:ebcdic-gb-285+euro 1146 cp1146 cp01146 ccsid01146
Name:IBM01147  DisplayName:IBM01147  Aliases:cp1147 1147 cp01147 ccsid01147 ebcdic-fr-277+euro
Name:IBM01148  DisplayName:IBM01148  Aliases:cp1148 ebcdic-international-500+euro 1148 cp01148 ccsid01148
Name:IBM01149  DisplayName:IBM01149  Aliases:ebcdic-s-871+euro 1149 cp1149 cp01149 ccsid01149
Name:IBM037  DisplayName:IBM037  Aliases:cp037 ibm037 ibm-037 csIBM037 ebcdic-cp-us ebcdic-cp-ca ebcdic-cp-nl ebcdic-cp-wt 037 cpibm37 cs-ebcdic-cp-wt ibm-37 cs-ebcdic-cp-us cs-ebcdic-cp-ca cs-ebcdic-cp-nl
Name:IBM1026  DisplayName:IBM1026  Aliases:cp1026 ibm-1026 1026 ibm1026
Name:IBM1047  DisplayName:IBM1047  Aliases:ibm-1047 1047 cp1047
Name:IBM273  DisplayName:IBM273  Aliases:ibm-273 ibm273 273 cp273
Name:IBM277  DisplayName:IBM277  Aliases:ibm277 277 cp277 ibm-277
Name:IBM278  DisplayName:IBM278  Aliases:cp278 278 ibm-278 ebcdic-cp-se csIBM278 ibm278 ebcdic-sv
Name:IBM280  DisplayName:IBM280  Aliases:ibm280 280 cp280 ibm-280
Name:IBM284  DisplayName:IBM284  Aliases:csIBM284 ibm-284 cpibm284 ibm284 284 cp284
Name:IBM285  DisplayName:IBM285  Aliases:csIBM285 cp285 ebcdic-gb ibm-285 cpibm285 ibm285 285 ebcdic-cp-gb
Name:IBM290  DisplayName:IBM290  Aliases:ibm290 290 cp290 EBCDIC-JP-kana csIBM290 ibm-290
Name:IBM297  DisplayName:IBM297  Aliases:297 csIBM297 cp297 ibm297 ibm-297 cpibm297 ebcdic-cp-fr
Name:IBM420  DisplayName:IBM420  Aliases:ibm420 420 cp420 csIBM420 ibm-420 ebcdic-cp-ar1
Name:IBM424  DisplayName:IBM424  Aliases:ebcdic-cp-he csIBM424 ibm-424 ibm424 424 cp424
Name:IBM437  DisplayName:IBM437  Aliases:ibm437 437 ibm-437 cspc8codepage437 cp437 windows-437
Name:IBM500  DisplayName:IBM500  Aliases:ibm-500 ibm500 500 ebcdic-cp-bh ebcdic-cp-ch csIBM500 cp500
Name:IBM775  DisplayName:IBM775  Aliases:ibm-775 ibm775 775 cp775
Name:IBM850  DisplayName:IBM850  Aliases:cp850 cspc850multilingual ibm850 850 ibm-850
Name:IBM852  DisplayName:IBM852  Aliases:csPCp852 ibm-852 ibm852 852 cp852
Name:IBM855  DisplayName:IBM855  Aliases:ibm855 855 ibm-855 cp855 cspcp855
Name:IBM857  DisplayName:IBM857  Aliases:ibm857 857 cp857 csIBM857 ibm-857
Name:IBM860  DisplayName:IBM860  Aliases:ibm860 860 cp860 csIBM860 ibm-860
Name:IBM861  DisplayName:IBM861  Aliases:cp861 ibm861 861 ibm-861 cp-is csIBM861
Name:IBM862  DisplayName:IBM862  Aliases:csIBM862 cp862 ibm862 862 cspc862latinhebrew ibm-862
Name:IBM863  DisplayName:IBM863  Aliases:csIBM863 ibm-863 ibm863 863 cp863
Name:IBM864  DisplayName:IBM864  Aliases:csIBM864 ibm-864 ibm864 864 cp864
Name:IBM865  DisplayName:IBM865  Aliases:ibm-865 csIBM865 cp865 ibm865 865
Name:IBM866  DisplayName:IBM866  Aliases:ibm866 866 ibm-866 csIBM866 cp866
Name:IBM868  DisplayName:IBM868  Aliases:ibm868 868 cp868 csIBM868 ibm-868 cp-ar
Name:IBM869  DisplayName:IBM869  Aliases:cp869 ibm869 869 ibm-869 cp-gr csIBM869
Name:IBM870  DisplayName:IBM870  Aliases:870 cp870 csIBM870 ibm-870 ibm870 ebcdic-cp-roece ebcdic-cp-yu
Name:IBM871  DisplayName:IBM871  Aliases:ibm871 871 cp871 ebcdic-cp-is csIBM871 ibm-871
Name:IBM918  DisplayName:IBM918  Aliases:918 ibm-918 ebcdic-cp-ar2 cp918
Name:ISO-2022-CN  DisplayName:ISO-2022-CN  Aliases:csISO2022CN ISO2022CN
Name:ISO-2022-JP  DisplayName:ISO-2022-JP  Aliases:csjisencoding iso2022jp jis_encoding jis csISO2022JP
Name:ISO-2022-JP-2  DisplayName:ISO-2022-JP-2  Aliases:csISO2022JP2 iso2022jp2
Name:ISO-2022-KR  DisplayName:ISO-2022-KR  Aliases:csISO2022KR ISO2022KR
Name:ISO-8859-1  DisplayName:ISO-8859-1  Aliases:819 ISO8859-1 l1 ISO_8859-1:1987 ISO_8859-1 8859_1 iso-ir-100 latin1 cp819 ISO8859_1 IBM819 ISO_8859_1 IBM-819 csISOLatin1
Name:ISO-8859-13  DisplayName:ISO-8859-13  Aliases:iso_8859-13 ISO8859-13 iso8859_13 8859_13
Name:ISO-8859-15  DisplayName:ISO-8859-15  Aliases:ISO8859-15 LATIN0 ISO8859_15_FDIS ISO8859_15 cp923 8859_15 L9 ISO-8859-15 IBM923 csISOlatin9 ISO_8859-15 IBM-923 csISOlatin0 923 LATIN9
Name:ISO-8859-2  DisplayName:ISO-8859-2  Aliases:ISO8859-2 ibm912 l2 ISO_8859-2 8859_2 cp912 ISO_8859-2:1987 iso8859_2 iso-ir-101 latin2 912 csISOLatin2 ibm-912
Name:ISO-8859-3  DisplayName:ISO-8859-3  Aliases:ISO8859-3 ibm913 8859_3 l3 cp913 ISO_8859-3 iso8859_3 latin3 csISOLatin3 913 ISO_8859-3:1988 ibm-913 iso-ir-109
Name:ISO-8859-4  DisplayName:ISO-8859-4  Aliases:8859_4 latin4 l4 cp914 ISO_8859-4:1988 ibm914 ISO_8859-4 iso-ir-110 iso8859_4 csISOLatin4 iso8859-4 914 ibm-914
Name:ISO-8859-5  DisplayName:ISO-8859-5  Aliases:ISO_8859-5:1988 csISOLatinCyrillic iso-ir-144 iso8859_5 cp915 8859_5 ibm-915 ISO_8859-5 ibm915 915 cyrillic ISO8859-5
Name:ISO-8859-6  DisplayName:ISO-8859-6  Aliases:ASMO-708 8859_6 iso8859_6 ISO_8859-6 csISOLatinArabic ibm1089 arabic ibm-1089 1089 ECMA-114 iso-ir-127 ISO_8859-6:1987 ISO8859-6 cp1089
Name:ISO-8859-7  DisplayName:ISO-8859-7  Aliases:greek 8859_7 greek8 ibm813 ISO_8859-7 iso8859_7 ELOT_928 cp813 ISO_8859-7:1987 sun_eu_greek csISOLatinGreek iso-ir-126 813 iso8859-7 ECMA-118 ibm-813
Name:ISO-8859-8  DisplayName:ISO-8859-8  Aliases:8859_8 ISO_8859-8 ISO_8859-8:1988 cp916 iso-ir-138 ISO8859-8 hebrew iso8859_8 ibm-916 csISOLatinHebrew 916 ibm916
Name:ISO-8859-9  DisplayName:ISO-8859-9  Aliases:ibm-920 ISO_8859-9 8859_9 ISO_8859-9:1989 ibm920 latin5 l5 iso8859_9 cp920 920 iso-ir-148 ISO8859-9 csISOLatin5
Name:JIS_X0201  DisplayName:JIS_X0201  Aliases:JIS0201 csHalfWidthKatakana X0201 JIS_X0201
Name:JIS_X0212-1990  DisplayName:JIS_X0212-1990  Aliases:JIS0212 iso-ir-159 x0212 jis_x0212-1990 csISO159JISX02121990
Name:KOI8-R  DisplayName:KOI8-R  Aliases:koi8_r koi8 cskoi8r
Name:KOI8-U  DisplayName:KOI8-U  Aliases:koi8_u
Name:Shift_JIS  DisplayName:Shift_JIS  Aliases:shift_jis x-sjis sjis shift-jis ms_kanji csShiftJIS
Name:TIS-620  DisplayName:TIS-620  Aliases:tis620 tis620.2533
Name:US-ASCII  DisplayName:US-ASCII  Aliases:ANSI_X3.4-1968 cp367 csASCII iso-ir-6 ASCII iso_646.irv:1983 ANSI_X3.4-1986 ascii7 default ISO_646.irv:1991 ISO646-US IBM367 646 us
Name:UTF-16  DisplayName:UTF-16  Aliases:UTF_16 unicode utf16 UnicodeBig
Name:UTF-16BE  DisplayName:UTF-16BE  Aliases:X-UTF-16BE UTF_16BE ISO-10646-UCS-2 UnicodeBigUnmarked
Name:UTF-16LE  DisplayName:UTF-16LE  Aliases:UnicodeLittleUnmarked UTF_16LE X-UTF-16LE
Name:UTF-32  DisplayName:UTF-32  Aliases:UTF_32 UTF32
Name:UTF-32BE  DisplayName:UTF-32BE  Aliases:X-UTF-32BE UTF_32BE
Name:UTF-32LE  DisplayName:UTF-32LE  Aliases:X-UTF-32LE UTF_32LE
Name:UTF-8  DisplayName:UTF-8  Aliases:unicode-1-1-utf-8 UTF8
Name:windows-1250  DisplayName:windows-1250  Aliases:cp1250 cp5346
Name:windows-1251  DisplayName:windows-1251  Aliases:cp5347 ansi-1251 cp1251
Name:windows-1252  DisplayName:windows-1252  Aliases:cp5348 cp1252
Name:windows-1253  DisplayName:windows-1253  Aliases:cp1253 cp5349
Name:windows-1254  DisplayName:windows-1254  Aliases:cp1254 cp5350
Name:windows-1255  DisplayName:windows-1255  Aliases:cp1255
Name:windows-1256  DisplayName:windows-1256  Aliases:cp1256
Name:windows-1257  DisplayName:windows-1257  Aliases:cp1257 cp5353
Name:windows-1258  DisplayName:windows-1258  Aliases:cp1258
Name:windows-31j  DisplayName:windows-31j  Aliases:MS932 windows-932 csWindows31J
Name:x-Big5-HKSCS-2001  DisplayName:x-Big5-HKSCS-2001  Aliases:Big5_HKSCS_2001 big5-hkscs-2001 big5hk-2001 big5-hkscs:unicode3.0 big5hkscs-2001
Name:x-Big5-Solaris  DisplayName:x-Big5-Solaris  Aliases:Big5_Solaris
Name:x-euc-jp-linux  DisplayName:x-euc-jp-linux  Aliases:euc_jp_linux euc-jp-linux
Name:x-EUC-TW  DisplayName:x-EUC-TW  Aliases:euctw cns11643 EUC-TW euc_tw
Name:x-eucJP-Open  DisplayName:x-eucJP-Open  Aliases:eucJP-open EUC_JP_Solaris
Name:x-IBM1006  DisplayName:x-IBM1006  Aliases:ibm1006 ibm-1006 1006 cp1006
Name:x-IBM1025  DisplayName:x-IBM1025  Aliases:ibm-1025 1025 cp1025 ibm1025
Name:x-IBM1046  DisplayName:x-IBM1046  Aliases:ibm1046 ibm-1046 1046 cp1046
Name:x-IBM1097  DisplayName:x-IBM1097  Aliases:ibm1097 ibm-1097 1097 cp1097
Name:x-IBM1098  DisplayName:x-IBM1098  Aliases:ibm-1098 1098 cp1098 ibm1098
Name:x-IBM1112  DisplayName:x-IBM1112  Aliases:ibm1112 ibm-1112 1112 cp1112
Name:x-IBM1122  DisplayName:x-IBM1122  Aliases:cp1122 ibm1122 ibm-1122 1122
Name:x-IBM1123  DisplayName:x-IBM1123  Aliases:ibm1123 ibm-1123 1123 cp1123
Name:x-IBM1124  DisplayName:x-IBM1124  Aliases:ibm-1124 1124 cp1124 ibm1124
Name:x-IBM1166  DisplayName:x-IBM1166  Aliases:cp1166 ibm1166 ibm-1166 1166
Name:x-IBM1364  DisplayName:x-IBM1364  Aliases:cp1364 ibm1364 ibm-1364 1364
Name:x-IBM1381  DisplayName:x-IBM1381  Aliases:cp1381 ibm-1381 1381 ibm1381
Name:x-IBM1383  DisplayName:x-IBM1383  Aliases:ibm1383 ibm-1383 1383 cp1383
Name:x-IBM300  DisplayName:x-IBM300  Aliases:cp300 ibm300 300 ibm-300
Name:x-IBM33722  DisplayName:x-IBM33722  Aliases:33722 ibm-33722 cp33722 ibm33722 ibm-5050 ibm-33722_vascii_vpua
Name:x-IBM737  DisplayName:x-IBM737  Aliases:cp737 ibm737 737 ibm-737
Name:x-IBM833  DisplayName:x-IBM833  Aliases:ibm833 cp833 ibm-833
Name:x-IBM834  DisplayName:x-IBM834  Aliases:ibm834 834 cp834 ibm-834
Name:x-IBM856  DisplayName:x-IBM856  Aliases:ibm856 856 cp856 ibm-856
Name:x-IBM874  DisplayName:x-IBM874  Aliases:ibm-874 ibm874 874 cp874
Name:x-IBM875  DisplayName:x-IBM875  Aliases:ibm-875 ibm875 875 cp875
Name:x-IBM921  DisplayName:x-IBM921  Aliases:ibm921 921 ibm-921 cp921
Name:x-IBM922  DisplayName:x-IBM922  Aliases:ibm922 922 cp922 ibm-922
Name:x-IBM930  DisplayName:x-IBM930  Aliases:ibm-930 ibm930 930 cp930
Name:x-IBM933  DisplayName:x-IBM933  Aliases:ibm933 933 cp933 ibm-933
Name:x-IBM935  DisplayName:x-IBM935  Aliases:cp935 ibm935 935 ibm-935
Name:x-IBM937  DisplayName:x-IBM937  Aliases:ibm-937 ibm937 937 cp937
Name:x-IBM939  DisplayName:x-IBM939  Aliases:ibm-939 cp939 ibm939 939
Name:x-IBM942  DisplayName:x-IBM942  Aliases:ibm-942 cp942 ibm942 942
Name:x-IBM942C  DisplayName:x-IBM942C  Aliases:ibm942C cp942C ibm-942C 942C
Name:x-IBM943  DisplayName:x-IBM943  Aliases:ibm943 943 ibm-943 cp943
Name:x-IBM943C  DisplayName:x-IBM943C  Aliases:943C cp943C ibm943C ibm-943C
Name:x-IBM948  DisplayName:x-IBM948  Aliases:ibm-948 ibm948 948 cp948
Name:x-IBM949  DisplayName:x-IBM949  Aliases:ibm-949 ibm949 949 cp949
Name:x-IBM949C  DisplayName:x-IBM949C  Aliases:ibm949C ibm-949C cp949C 949C
Name:x-IBM950  DisplayName:x-IBM950  Aliases:cp950 ibm950 950 ibm-950
Name:x-IBM964  DisplayName:x-IBM964  Aliases:ibm-964 cp964 ibm964 964
Name:x-IBM970  DisplayName:x-IBM970  Aliases:ibm970 ibm-eucKR 970 cp970 ibm-970
Name:x-ISCII91  DisplayName:x-ISCII91  Aliases:ISCII91 iso-ir-153 iscii ST_SEV_358-88 csISO153GOST1976874
Name:x-ISO-2022-CN-CNS  DisplayName:x-ISO-2022-CN-CNS  Aliases:ISO2022CN_CNS ISO-2022-CN-CNS
Name:x-ISO-2022-CN-GB  DisplayName:x-ISO-2022-CN-GB  Aliases:ISO2022CN_GB ISO-2022-CN-GB
Name:x-iso-8859-11  DisplayName:x-iso-8859-11  Aliases:iso-8859-11 iso8859_11
Name:x-JIS0208  DisplayName:x-JIS0208  Aliases:JIS0208 JIS_C6226-1983 iso-ir-87 x0208 JIS_X0208-1983 csISO87JISX0208
Name:x-JISAutoDetect  DisplayName:x-JISAutoDetect  Aliases:JISAutoDetect
Name:x-Johab  DisplayName:x-Johab  Aliases:ms1361 ksc5601_1992 johab ksc5601-1992
Name:x-MacArabic  DisplayName:x-MacArabic  Aliases:MacArabic
Name:x-MacCentralEurope  DisplayName:x-MacCentralEurope  Aliases:MacCentralEurope
Name:x-MacCroatian  DisplayName:x-MacCroatian  Aliases:MacCroatian
Name:x-MacCyrillic  DisplayName:x-MacCyrillic  Aliases:MacCyrillic
Name:x-MacDingbat  DisplayName:x-MacDingbat  Aliases:MacDingbat
Name:x-MacGreek  DisplayName:x-MacGreek  Aliases:MacGreek
Name:x-MacHebrew  DisplayName:x-MacHebrew  Aliases:MacHebrew
Name:x-MacIceland  DisplayName:x-MacIceland  Aliases:MacIceland
Name:x-MacRoman  DisplayName:x-MacRoman  Aliases:MacRoman
Name:x-MacRomania  DisplayName:x-MacRomania  Aliases:MacRomania
Name:x-MacSymbol  DisplayName:x-MacSymbol  Aliases:MacSymbol
Name:x-MacThai  DisplayName:x-MacThai  Aliases:MacThai
Name:x-MacTurkish  DisplayName:x-MacTurkish  Aliases:MacTurkish
Name:x-MacUkraine  DisplayName:x-MacUkraine  Aliases:MacUkraine
Name:x-MS932_0213  DisplayName:x-MS932_0213  Aliases:
Name:x-MS950-HKSCS  DisplayName:x-MS950-HKSCS  Aliases:MS950_HKSCS
Name:x-MS950-HKSCS-XP  DisplayName:x-MS950-HKSCS-XP  Aliases:MS950_HKSCS_XP
Name:x-mswin-936  DisplayName:x-mswin-936  Aliases:ms936 ms_936
Name:x-PCK  DisplayName:x-PCK  Aliases:pck
Name:x-SJIS_0213  DisplayName:x-SJIS_0213  Aliases:
Name:x-UTF-16LE-BOM  DisplayName:x-UTF-16LE-BOM  Aliases:UnicodeLittle
Name:X-UTF-32BE-BOM  DisplayName:X-UTF-32BE-BOM  Aliases:UTF_32BE_BOM UTF-32BE-BOM
Name:X-UTF-32LE-BOM  DisplayName:X-UTF-32LE-BOM  Aliases:UTF_32LE_BOM UTF-32LE-BOM
Name:x-windows-50220  DisplayName:x-windows-50220  Aliases:cp50220 ms50220
Name:x-windows-50221  DisplayName:x-windows-50221  Aliases:cp50221 ms50221
Name:x-windows-874  DisplayName:x-windows-874  Aliases:ms-874 ms874 windows-874
Name:x-windows-949  DisplayName:x-windows-949  Aliases:windows949 ms949 windows-949 ms_949
Name:x-windows-950  DisplayName:x-windows-950  Aliases:ms950 windows-950
Name:x-windows-iso2022jp  DisplayName:x-windows-iso2022jp  Aliases:windows-iso2022jp
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170

这些编码的实现类都是sun包下的:

有了Charset对象即可获取CharsetDecoder(解码器)和CharsetEncoder(编码器)。

java软件国际化解决方案相关推荐

  1. java国际化软件_JavaWeb开发——软件国际化(动态元素国际化)

    软件国际化的第二个部分,就是动态元素国际化. 数值,货币,时间,日期等数据由于可能在程序运行时动态产生,所以无法像文字一样简单地将它们从应用程序中分离出来,而是需要特殊处理.Java 中提供了解决这些 ...

  2. 软件本地化/国际化解决方案 - 多语种代码生成工具

    提起程序信息本地化/国际化解决方案(本地化和国际化是指让软件支持多国语言的显示), 很多人首先可能会想到大名鼎鼎的GNU GetText, 的确这是一个很优秀的解决方案.另外,还有一种方式是操作程序的 ...

  3. java 软件开发面试宝典

    一. Java 基础部分........................................................................................ ...

  4. *Java软件开发面试知识整理*

    Java软件开发面试知识整理 围绕以下几点回答问题:是什么.为什么.什么时候用.项目实现.解决什么问题.遇到的困难 谈谈你对Java和C的理解? Java: 面向对象.Unicode:可以跨平台(JV ...

  5. [JAVA软件工程师-面试宝典-2013最新版]

    http://blog.csdn.net/u012099645/article/details/13756447 [JAVA面试宝典-2013最新版] 一. Java基础部分............. ...

  6. java软件工程师工作业绩_java软件工程师,工作总结

    java 软件工程师 , 工作总结 篇一:软件开发工程师个人年终工作总结范文 软件开发工程师个人年终工作总结范文 作为一个软件开发工程师(我也是一名软件开发工程 师) ,所实在的如果每年只做那么一两个 ...

  7. black duck 下载_如何创建安全的Java软件:与Black Duck的Tim Mackey交谈

    black duck 下载 在TheServerSide对安全Java软件开发的持续报道中,我最近与Black Duck Software的IT传播者Tim Mackey进行了交谈. 这次对话非常有趣 ...

  8. 湛蓝.Net软件国际化工具V1.0.0.发布了,欢迎大家使用

    集资源提取,自动翻译,资源集成与一体的一个完整的国际化解决方案的工具 支持Vb,C#两种开发语言,支持VS2003,VS2005两种开发平台,支持WEb,Win两种应用类型 不用任何手工编码就可实现软 ...

  9. Java软件工程师 (职业简介)

    Java软件工程师 引言:信息时代的迅猛发展使得软件工程师十分抢手,而其中的java软件工程师更是备受青睐.那么,如何才能成为Java软件工程师?Java软件工程师又有怎样的发展前途?本文将为你一一解 ...

最新文章

  1. 以太网的MAC帧(二)
  2. Table 'mysql.plugin' doesn't exist引发de血案
  3. 数组array的一些用法
  4. 可以用推理来过度分析《无穷动》
  5. Serverless那么火,2019年的采用如何?
  6. 一次动态代理的填坑之旅
  7. DotNET内存管理与垃圾回收[转]
  8. input输入框清除样式
  9. 由于简繁汉字一对多而导致经常写错的繁体字
  10. IDM下载器最新版本6.32.7
  11. 开发本地O2O分销系统有什么优势 O2O电子商务模式有哪些特点?
  12. 数据库原理及应用习题三
  13. 国内各运营商(ISP)IP段表
  14. ★关于人类体质弱化的分析
  15. linux调用一个函数失败 打印错误,write函数出现错误invalid argument
  16. 【python数据结构】多维数组
  17. HUD(蓝牙版)中蓝牙方案
  18. 代码随想录Day48|198.打家劫舍、213.打家劫舍II、337.打家劫舍III
  19. 【app开发学习】APP开发的标准流程
  20. IMSI、IMEI和MEID(ESN)

热门文章

  1. MFC单文档之给主窗口添加背景图片
  2. bzoj 1503 (权值线段树)
  3. 一名菜鸟程序猿对前端的简单理解及介绍
  4. pytorch锁死在dataloader(训练时卡死)
  5. 毕业设计 单片机指纹识别考勤系统 - 嵌入式 物联网
  6. AcWing 285. 没有上司的舞会
  7. NewTek LightWave 3D 2018 破解版
  8. 蜂窝移动网络是什么,它和 Wi-Fi 有什么区别? 蓝牙和无线有什么区别?
  9. 上升了百分之几怎么算_求增加百分之几的应用题
  10. Vue前端模板框架--vue-admin-template