在《java中一个字符到底多少个字节》中我叙述了java的char采用unicode-16编码表示,有些字符能用1个char表示(两个字节),而另一些不得不用2个char表示(4个字节), Character.isSurrogatePair(char high, char low)方法可以用来判定字符串中相邻的两个char表示一个字符还是表示两个字符,所以最后的代码为(注:我的MySQL用的字符集不支持扩展字符集,0x20001表示一个扩展字符):
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 |
public static void main(String[] args) { String str = "2015/2/12, 欢迎访问javacoder.cn" + String.valueOf(Character.toChars(0x20001)); Map<String, Integer> map = new LinkedHashMap<>(); for (int index = 0; index < str.length(); index++) { char high = str.charAt(index); //防止越界 char low = index == str.length() - 1 ? high : str.charAt(index + 1); int count = 1; boolean isSurrogate = Character.isSurrogatePair(high, low); String key = null; if (isSurrogate) { char[] arr = { high, low }; key = String.valueOf(arr); index++; } else { key = String.valueOf(high); } if (map.containsKey(key)) { count += map.get(key); } map.put(key, count); } for (Map.Entry<String, Integer> entry : map.entrySet()) { System.out.println("" + entry.getKey() + '|' + entry.getValue()); } } |
上面的代码片段我们使用的是unicode-16进行统计的,当然我们可以使用"utf-8"编码来进行统计,代码为:
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 |
public static void main_2(String[] args) throws UnsupportedEncodingException { String str = "2015/2/12, 欢迎访问javacoder.cn" + String.valueOf(Character.toChars(0x20001)); byte[] bytes = str.getBytes("utf-8"); Map<String, Integer> map = new LinkedHashMap<String, Integer>(); for (int index = 0; index < bytes.length;) { int b = bytes[index] & 0xff; int length = 1; //检查第一个字节的标志位 if ((b & 0xe0) == 0xc0) { // 110 length = 2; } else if ((b & 0xf0) == 0xe0) { // 1110 length = 3; } else if ((b & 0xf8) == 0xf0) { // 11110 length = 4; } else if ((b & 0xfc) == 0xf8) { // 1111 10 length = 5; } else if ((b & 0xfe) == 0xfc) {// 1111 110 length = 6; } String key = new String(bytes, index, length, "utf-8"); int count = 1; if (map.containsKey(key)) { count += map.get(key); } map.put(key, count); index = index + length; } for (Map.Entry<String, Integer> entry : map.entrySet()) { System.out.println("" + entry.getKey() + '|' + entry.getValue()); } } |
Posted in: 面试加油站
Comments are closed.