1. 国际化编程
- Java是第一个设计成支持国际化的编程语言
- java.util.ResourceBundle 用于加载一个语言_国家语言包
- java.util.Locale 定义一个语言_国家
- java.text.MessageFormat 用于格式化带占位符的字符串
- java.text.NumberFormat 用于格式化数字/金额
- java.text.DateFormat 用于格式化日期时间
- java.time.format.DateTimeFormatter 用于格式化日期时间
Locale类
- Locale(zh_CN, en_US,…)
- 语言,zh,en等
- 国家/地区,CN,US等
- 其他变量(variant)(几乎不用)
- Locale方法
- getAvailableLocales()返回所有的可用Locale
- getDefault()返回默认的Locale
语言文件
- 一个Properties文件
- 包含K-V对,每行一个K-V,例如:age=20
- 命名规则
- 包名_语言_国家地区.properties, (语言和国家地区可选)
e.g. message_zh_CN.properties - 存储文件必须是ASCII码文件
- 如果是ASCII以外的文字,必须用Unicode的表示\uxxxx
- 可以采用native2ascii.exe (%JAVA_HOME%\bin目录下)进行转码
- 包名_语言_国家地区.properties, (语言和国家地区可选)
ResourceBundle类
- ResourceBundle
- 根据Locale要求,加载语言文件(Properties文件),存储K-V对
1
2Locale myLocale = new Locale("zh", "CN");
ResourceBundle.getBundle("msg", myLocale); //加载msg_zh_CN.properties - getString(String key) 返回所对应的value
- 如果找不到key,则报异常
- 语言文件层级结构
- 文件: 包名_当前Locale语言_当前Locale国家地区_当前Locale变量(variant)
- msg_zh_CN.properties (注意大小写)
- msg_zh.properties
- msg.properties
- 文件形成树结构
- ResourceBundle 加载文件
- 首先,按如下顺序找到第一个Properties文件
- 包名_当前Locale语言_当前Locale国家地区_当前Locale变量(variant)
- 包名_当前Locale语言_当前Locale国家地区
- 包名_当前Locale语言
- 包名_默认Locale语言_默认Locale国家地区_默认Locale变量(variant)
- 包名_默认Locale语言_默认Locale国家地区
- 包名_默认Locale语言
- 包名
- 根据Properties树结构,把第一步的Properties文件及父级文件全部加载,作为后续的K-V集合
2. 高级字符串处理
正则表达式
- 用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”
- 作用
- 测试字符串内的模式
- 识别/替换文本
- 提取文本
java.util.regex包
- Pattern类 正则表达式的编译表示
- compile 编译一个正则表达式为Pattern对象
- matcher 用Pattern对象匹配一个字符串,返回匹配结果
1
2
3
4private static final String REGEX = "\\bdog\\b"; //\b表示边界
private static final String INPUT = "dog dog dog doggie dogg";
Pattern p = Pattern.compile(REGEX);
Matcher m = p.matcher(INPUT); - Matcher类
- Index Methods(位置方法)
- start(), start(int group), end(), end(int group)
1
2
3
4while (m.find()) {
System.out.println("start(): " + m.start()); //开始位置
System.out.println("end(): " + m.end()); //结束位置
}- Study Methods(查找方法)
- lookingAt(), find(), find(int start), matches()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16private static final String REGEX = "foo";
private static final String INPUT = "foooooooo";
private static Pattern pattern;
private static Matcher matcher;
public static void main(String[] args) {
// Initialize
pattern = Pattern.compile(REGEX);
matcher = pattern.matcher(INPUT);
System.out.println("Current REGEX is: " + REGEX);
System.out.println("Current INPUT is: " + INPUT);
System.out.println("lookingAt(): " + matcher.lookingAt()); //部分匹配
System.out.println("matches(): " + matcher.matches()); //完全匹配
}- Replacement Methods(替换方法)
- replaceAll(String replacement)
- appendReplacement方法:replaceAll方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16private static String REGEX = "a*b"; //*表示限定前面的a可以有0或者多个。
private static String INPUT = "aabfooaabfooabfoobcdd";
private static String REPLACE = "-";
public static void main(String[] args) {
Pattern p = Pattern.compile(REGEX);
Matcher m = p.matcher(INPUT); // get a matcher object
StringBuffer sb = new StringBuffer();
//全部替换
while(m.find()){
m.appendReplacement(sb,REPLACE);
}
//将最后的尾巴字符串附加上
m.appendTail(sb);
System.out.println(sb.toString());
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15private static String REGEX = "a*b"; //*表示限定前面的a可以有0或者多个。
private static String INPUT = "aabfooaabfooabfoobcdd";
private static String REPLACE = "-";
public static void main(String[] args) {
Pattern p = Pattern.compile(REGEX);
Matcher m = p.matcher(INPUT); // get a matcher object
StringBuffer sb = new StringBuffer();
//全部替换
while(m.find()){
m.appendReplacement(sb,REPLACE);
}
//将最后的尾巴字符串附加上
m.appendTail(sb);
System.out.println(sb.toString());
}
- appendReplacement方法:
其他字符串操作
- 字符串和集合互转
- [1,2,3], “1,2,3”
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
28import org.apache.commons.lang3.StringUtils;
List<String> names = new LinkedList<String>();
names.add("Xiaohong");
names.add("Xiaoming");
names.add("Daming");
names.add("Xiaohei");
//从ArrayList变到字符串
String str1 = String.join(",", names); //String.join, JDK 8 引入
System.out.println(str1);
String str2 = StringUtils.join(names, ","); //Apache Commons Lang
System.out.println(str2);
//从字符串变回ArrayList
List<String> names2 = Arrays.asList(str2.split(","));
for(String name:names2) {
System.out.println(name);
}
//StringUtils 可以支持更多数据类型
List<Integer> ids = new ArrayList<Integer>();
ids.add(1);
ids.add(3);
ids.add(5);
String str3 = StringUtils.join(ids, ",");
System.out.println(str3); - 字符串转义
- 对关键字符转义
1
2
3
4
5
6
7
8
9
10import org.apache.commons.text.StringEscapeUtils;
String str = "He didn't say, \"Stop!\"";
//转义
String escapedStr = StringEscapeUtils.escapeJava(str);
System.out.println("escape" + ":" + escapedStr);
//从转义字符串转回来
String str2 = StringEscapeUtils.unescapeJava(escapedStr);
System.out.println("unescape" + ":" + str2); - 变量名字格式化
- 名字驼峰命名
1
2
3
4import com.google.common.base.CaseFormat;
String s1 = "CONSTANT_NAME";
String s2 = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, s1);
System.out.println(s2); //constantName; - 字符串输入流
- 将字符串转为一个输入流
- 输入流可以定义为Scanner(OJ实现原理)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25import org.apache.commons.io.Charsets;
import org.apache.commons.io.IOUtils;
//构造字符串列表
List<String> names = new LinkedList<String>();
names.add("Xiaohong");
names.add("Xiaoming");
names.add("Daming");
names.add("Xiaohei");
//合并为一个字符串,以逗号相连
String nameStr = String.join(",",names);
//将字符串作为默认的输入流
InputStream in = IOUtils.toInputStream(nameStr, Charsets.toCharset("UTF-8"));
//重置系统的输入流
System.setIn(in);
//模拟键盘输入 这也是OJ平台测试用例输入的原理
//此处也可以换成一个文件输入流
Scanner sc=new Scanner(System.in);
sc.useDelimiter(",");
while(sc.hasNext())
{
System.out.println(sc.next());
}