獲取中文首字母
有時(shí)候,比如微信上根據(jù)名字拼音首字母排序并檢索。那么用Java獲取中文首字母是怎么實(shí)現(xiàn)的呢?
代碼
不多說,直接上代碼:(寫個(gè)工具類)
public class FirstCharUtil {
// 簡(jiǎn)體中文的編碼范圍從B0A1(45217)一直到F7FE(63486)
private static int BEGIN = 45217;
private static int END = 63486;
// 按照聲 母表示,這個(gè)表是在GB2312中的出現(xiàn)的第一個(gè)漢字,
//也就是說“啊”是代表首字母a的第一個(gè)漢字。
// i, u, v都不做聲母, 自定規(guī)則跟隨前面的字母
private static char[] charTable = { '啊', '芭', '擦', '搭', '蛾', '發(fā)', '噶', '哈',
'哈', '擊', '喀', '垃', '媽', '拿', '哦', '啪', '期', '然', '撒', '塌', '塌',
'塌', '挖', '昔', '壓', '匝', };
// 二十六個(gè)字母區(qū)間對(duì)應(yīng)二十七個(gè)端點(diǎn)
// GB2312碼漢字區(qū)間十進(jìn)制表示
private static int[] table = new int[27];
// 對(duì)應(yīng)首字母區(qū)間表
private static char[] initialTable = { 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'H', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'T', 'T', 'W', 'X', 'Y', 'Z', };
// 初始化
static {
for (int i = 0; i < 26; i++) {
// 得到GB2312碼的首字母區(qū)間端點(diǎn)表,十進(jìn)制。
table[i] = gbValue(charTable[i]);
}
table[26] = END;// 區(qū)間表結(jié)尾
}
// ------------------------public方法區(qū)------------------------
// 根據(jù)一個(gè)包含漢字的字符串返回一個(gè)漢字拼音首字母的字符串。
public static String first(String S) {
String Result = "";
if (S == null || S.equals("")) {
return "#";
}
char cs = S.charAt(0);
try {
Result += Char2Initial(cs);
} catch (Exception e) {
Result = "%";
e.printStackTrace();
}
return Result;
}
// ------------------------private方法區(qū)------------------------
/**
* 輸入字符,得到他的聲母,英文字母返回對(duì)應(yīng)的大寫字母,其他非簡(jiǎn)體漢字返回 '#'
*/
private static char Char2Initial(char ch) {
// 對(duì)英文字母的處理:小寫字母轉(zhuǎn)換為大寫,大寫的直接返回
if (ch >= 'a' && ch <= 'z') {
return (char) (ch - 'a' + 'A');
}
if (ch >= 'A' && ch <= 'Z') {
return ch;
}
// 對(duì)非英文字母的處理:轉(zhuǎn)化為首字母,然后判斷是否在碼表范圍內(nèi),
// 若不是,則直接返回。
// 若是,則在碼表內(nèi)的進(jìn)行判斷。
int gb = gbValue(ch);// 漢字轉(zhuǎn)換首字母
if ((gb < BEGIN) || (gb > END))// 在碼表區(qū)間之前,直接返回
{
return '#';
}
int i;
for (i = 0; i < 26; i++) {
// 判斷匹配碼表區(qū)間,匹配到就break,判斷區(qū)間形如“[,)”
if ((gb >= table[i]) && (gb < table[i + 1])) {
break;
}
}
if (gb == END) {// 補(bǔ)上GB2312區(qū)間最右端
i = 25;
}
return initialTable[i]; // 在碼表區(qū)間中,返回首字母
}
/**
* 取出漢字的編碼 cn 漢字
*/
private static int gbValue(char ch) {// 將一個(gè)漢字(GB2312)轉(zhuǎn)換為十進(jìn)制表示。
String str = new String();
str += ch;
try {
byte[] bytes = str.getBytes("GB2312");
if (bytes.length < 2) {
return 0;
}
return (bytes[0] << 8 & 0xff00) + (bytes[1] & 0xff);
} catch (Exception e) {
return 0;
}
}
}
使用方式:
String first = FirstCharUtil.first("加哇");
說明
- 原理: GB2312編碼中的中文是按照拼音排序的。
- 注意:一些生僻的字無法獲得正確的首字母,原因是這些字都是后加入的。(所以有些名字在通訊錄的排序不太一樣。)

配一張圖
其他
比較好用的第三方庫:漢語拼音庫。
implementation 'com.belerweb:pinyin4j:2.5.1'
使用:
@NonNull
public static String first(@Nullable String str) {
if (str == null || str.equals("")) {
return "#";
}
char ch = str.charAt(0);
if (ch >= 'a' && ch <= 'z') {
return (char) (ch - 'a' + 'A') + "";
}
if (ch >= 'A' && ch <= 'Z') {
return ch + "";
}
try {
HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
// 設(shè)置大小寫格式
defaultFormat.setCaseType(HanyuPinyinCaseType.UPPERCASE);
// 設(shè)置聲調(diào)格式:
defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
if (Character.toString(ch).matches("[\\u4E00-\\u9FA5]+")) {
String[] array = PinyinHelper.toHanyuPinyinStringArray(ch, defaultFormat);
if (array != null) {
return array[0].charAt(0) + "";
}
}
} catch (Exception e) {
e.printStackTrace();
}
return "#";
}
HanyuPinyin(漢語拼音),太真實(shí)了????。