Oracle的nlssort函數 java實現按拼音排序

  • lssort函數的作用是對字段排序,字符串類型的

    1.按拼音排序:

    select * from MEMBER t order by NLSSORT(t.b,'NLS_SORT = SCHINESE_PINYIN_M')

    nlssort方法/函數 oracle
     

    2.按筆畫排序:

    select * from MEMBER t order by NLSSORT(t.b,'NLS_SORT = SCHINESE_STROKE_M')

    nlssort方法/函數 oracle
     

    3.按部首排序:

    select * from MEMBER t order by NLSSORT(t.b,'NLS_SORT = SCHINESE_RADICAL_M')

    nlssort方法/函數 oracle
     

    java 漢字按照拼音排序

    數據庫中按照拼音排序很簡單

    SELECT DISTINCT province_name, province_code FROM `metadata_township` ORDER BY convert(province_name USING gbk) asc

    一般的排序都是能正確的,但是有的多音字啥的會有點差別,例如重慶,按理說是重是“chong”,但是排序的時候會按照“zhong”,就會排在靠後的。

    Java中按照拼音排序

    我的list裏面是對象,對象裏面含有需要按照拼音排序的字段name,我用的lambda表達式來簡化代碼。

     
    1. /**
    2. *(o1, o2) -> Collator.getInstance(Locale.CHINA).compare(o1.getName(), o2.getName()) 排序規則,根據漢字的拼音來排序(升序)
    3. * list 是需要排序的集合
    4. */
    5. Collections.sort(list,(o1, o2) -> Collator.getInstance(Locale.CHINA).compare(o1.getName(), o2.getName()));
     

    根據這個得到的排序大部分都是正確的,跟前面sql裏面排序的結果差不多,多音字,生僻字會不準確。

    • 默認的 Collection.sort() 是按照 ASCII 碼排序, 不過, 有第二個重載方法, 第二個參數可以傳入 Comparator 對象
    • java.text.Collator 可以用於本地語言排序, 自身已經實現 Comparator 接口.Collator.getInstance(Locale.CHINA) 獲取到我們中文的 Collator 實例
    /**
     * 按照拼音首字母排序
     */
    @Test
    public void test() {
        List<String> data = new ArrayList<>(Arrays.asList("上海", "天津", "北京", "深圳", "廣州", "成都", "西安", "武漢", "鄭州", "邯鄲", "a", "z", "A", "Z"));
        
        Collator collator = Collator.getInstance(Locale.CHINA);
    	Collections.sort(data, collator);
    
        for (String str : data) {
            System.out.print(str + " ");
        }
    }

     

     

    java實現按拼音排序

     
    複製代碼
    List<WaPayFileVO> list =(List<WaPayFileVO>) dao.execQueryBeanList(pagesql, params.toArray(),  new BeanListProcessor(WaPayFileVO.class));
    
     if("asc".equals(page.getOrder()) && "pk_psnjob__pk_psndoc__name".equals(page.getSort())){
                Collections.sort(list, new Comparator<WaPayFileVO>() {
                    @Override
                    public int compare(WaPayFileVO o1, WaPayFileVO o2) {
                        return Collator.getInstance(Locale.CHINESE).compare(o1.getPk_psnjob__pk_psndoc__name(),o2.getPk_psnjob__pk_psndoc__name());
                    }
                });
            }else if("desc".equals(page.getOrder()) && "pk_psnjob__pk_psndoc__name".equals(page.getSort())){
                Collections.sort(list, new Comparator<WaPayFileVO>() {
                    @Override
                    public int compare(WaPayFileVO o1, WaPayFileVO o2) {
                        return -Collator.getInstance(Locale.CHINESE).compare(o1.getPk_psnjob__pk_psndoc__name(),o2.getPk_psnjob__pk_psndoc__name());
                    }
                });
            }
    複製代碼

    jdk自帶的Collator包涵的漢字太少了,對一些生僻的姓氏不能進行排序。推薦使用:

    import com.ibm.icu.text.Collator; 

    是ibm開發的針對編碼的工具包,非常好用。附pom文件:

    <dependency>  
                <groupId>com.ibm.icu</groupId>  
                <artifactId>icu4j</artifactId>  
                <version>57.1</version>  
            </dependency> 

    業務場景:

    一個list集合,裏面add了若干個實體類,針對該實體類排序的屬性爲String。

    使用技術,自定義list排序(JDK自帶),重寫Comparator接口的compare方法,漢字轉拼音技術:使用的pinyin4j。

    pinyin4j官網地址:http://pinyin4j.sourceforge.net/

    不想去官網下載的我這裏也有,地址爲:

    //tempRateList 爲需要進行自定義排序的集合,SpRate爲該集合的實體類,riskName爲排序的屬性。

    直接上方案:

    1、導入pinyin4j-2.5.0.jar;

    2、對自定義排序的類使用以下方法進行自定義排序;

    1. Collections.sort(tempRateList,new Comparator<SpRate>() {  
    2.     @Override  
    3.     public int compare(SpRate s1, SpRate s2) {  
    4.         String o1 = s1.getRiskName();  
    5.         String o2 = s2.getRiskName();  
    6.         for (int i = 0; i < o1.length() && i < o2.length(); i++) {  
    7.   
    8.         int codePoint1 = o1.charAt(i);  
    9.         int codePoint2 = o2.charAt(i);  
    10.   
    11.         if (Character.isSupplementaryCodePoint(codePoint1)  
    12.             || Character.isSupplementaryCodePoint(codePoint2)) {  
    13.         i++;  
    14.         }  
    15.   
    16.         if (codePoint1 != codePoint2) {  
    17.         if (Character.isSupplementaryCodePoint(codePoint1)  
    18.             || Character.isSupplementaryCodePoint(codePoint2)) {  
    19.             return codePoint1 - codePoint2;  
    20.         }  
    21.   
    22.         String pinyin1 = PinyinHelper.toHanyuPinyinStringArray((char) codePoint1) == null   
    23.                 ? null : PinyinHelper.toHanyuPinyinStringArray((char) codePoint1)[0];  
    24.         String pinyin2 = PinyinHelper.toHanyuPinyinStringArray((char) codePoint2) == null   
    25.                 ? null : PinyinHelper.toHanyuPinyinStringArray((char) codePoint2)[0];  
    26.   
    27.         if (pinyin1 != null && pinyin2 != null) { // 兩個字符都是漢字  
    28.             if (!pinyin1.equals(pinyin2)) {  
    29.             return pinyin1.compareTo(pinyin2);  
    30.             }  
    31.         } else {  
    32.             return codePoint1 - codePoint2;  
    33.         }  
    34.         }  
    35.     }  
    36.     return o1.length() - o2.length();  
    37.     }  
    38. });  


    3、方法結束後  tempRateList 對象就完成了自定義排序

     

     

    發表評論
    所有評論
    還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
    相關文章