天天看點

通訊錄擷取首字母,并以首字母歸類傳回

需求背景

最近在做的一個項目裡,有需要展示我的通訊錄功能,與前端溝通結果是我将通訊錄裡所有聯系人全部在接口裡返給他們,當然傳回的資料格式是按照首字母已經歸類好了的,整體傳回對象是一個Map<String,List>,key值就是首字母firstChar,value是所有首字母的集合list

具體實戰

pinyinUtil

在錄入通訊錄的時候, 根據錄入的中文服務端在入庫的時候取到中文對應的首字母存到表裡,這裡有一個jar包已經有很好的封裝方法。首先要引入

<!--漢語拼音-->
<dependency>
		<groupId>com.belerweb</groupId>
		<artifactId>pinyin4j</artifactId>
		<version>2.5.0</version>
</dependency>
           

然後看這裡提供的兩個方法,一個是将中文轉拼音,這個有可能有這樣的業務場景,另一個就是根據輸入字元串取首字母了,裡面邏輯還可以根據具體需求進行修改,我這裡是将特殊字元和數字全部按照#号處理,消防微信做的

import lombok.extern.slf4j.Slf4j;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

/**
 * @author zhangyu
 * @description 漢語拼音工具類
 * @date 2019/5/23 17:42
 */
@Slf4j
public class PinyinUtil {

    /**
     * 将文字轉為漢語拼音
     * @param chineseLanguage 要轉成拼音的中文
     */
    public static String convertToPinyin(String chineseLanguage){
        char[] cl_chars = chineseLanguage.trim().toCharArray();
        String pinyin = "";
        HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
        // 輸出拼音全部小寫
        defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
        // 不帶聲調
        defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        defaultFormat.setVCharType(HanyuPinyinVCharType.WITH_V) ;
        try {
            for (int i=0; i<cl_chars.length; i++){
                // 如果字元是中文,則将中文轉為漢語拼音
                if (String.valueOf(cl_chars[i]).matches("[\u4e00-\u9fa5]+")){
                    pinyin += PinyinHelper.toHanyuPinyinStringArray(cl_chars[i], defaultFormat)[0];
                } else {
                    // 如果字元不是中文,則不轉換
                    pinyin += cl_chars[i];
                }
            }
        } catch (BadHanyuPinyinOutputFormatCombination e) {
            log.info("字元:{},轉拼音異常,原因為{}",chineseLanguage,e);
        }
        return pinyin;
    }


    /**
     * 取第一個漢字的第一個字元
     * @Title: getFirstLetter
     * @Description: TODO
     * @return String
     * @throws
     */
    public static String getFirstLetter(String chineseLanguage){
        char[] cl_chars = chineseLanguage.trim().toCharArray();
        String pinyin = "";
        HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
        // 輸出拼音全部大寫
        defaultFormat.setCaseType(HanyuPinyinCaseType.UPPERCASE);
        // 不帶聲調
        defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        try {
            String str = String.valueOf(cl_chars[0]);
            // 如果字元是中文,則将中文轉為漢語拼音,并取第一個字母
            if (str.matches("[\u4e00-\u9fa5]+")) {
                pinyin = PinyinHelper.toHanyuPinyinStringArray(cl_chars[0], defaultFormat)[0].substring(0, 1);
            } else if (str.matches("[0-9]+")) {
                // 如果字元是數字,取數字
                //pinyin += cl_chars[0];
                //本次需求數字變成#
                return "#";
            } else if (str.matches("[a-zA-Z]+")) {
                // 如果字元是字母,取字母
                pinyin += cl_chars[0];
            } else {
                // 否則傳回'#'
                return "#";
            }
        } catch (BadHanyuPinyinOutputFormatCombination e) {
            log.info("字元:{},轉拼音異常,原因為{}",chineseLanguage,e);
        }
        if(chineseLanguage.startsWith("重慶") || chineseLanguage.startsWith("長沙")
                || chineseLanguage.startsWith("長春") ||chineseLanguage.startsWith("長治")){
            return "C";
        }
        if(chineseLanguage.startsWith("廈門")){
            return "X";
        }
        return pinyin;
    }

    public static void main(String[] args) {
        System.out.println(convertToPinyin("張飛"));
        System.out.println(getFirstLetter("長沙市"));
    }
}
           

有了擷取首字母入庫的前提條件後,再傳回前端通訊錄時,按照前端夥伴的需求将結果按照首字母歸類傳回

public Map<String,List<AddressBookVO>> list() {
        //僞代碼需要自己實作
        List<AddressBookVO> addressBookVOS = selectAll();
        //以首字母分組傳回
        Map<String,List<AddressBookVO>> resultMap = new HashMap<>();
        if (CollectionUtil.isNotEmpty(addressBookVOS)) { 
            for(AddressBookVO temp : addressBookVOS){
                //map中已存在
                if(resultMap.containsKey(temp.getFirstChar())){
                    resultMap.get(temp.getFirstChar()).add(temp);
                }else{
                    //map中不存在,建立key,用來存放資料
                    List<AddressBookVO> tmpList = new ArrayList<>();
                    tmpList.add(temp);
                    resultMap.put(temp.getFirstChar(), tmpList);
                }
            }
        }
        return resultMap;
    }
           

上面這個方法,同樣适用于在一個list裡面按照某個字段進行分類的場景。