对象排序与按汉语拼音排序

对象排序与按汉语拼音排序

在项目开发中,经常会遇到一些排序的问题。
现在有一个操作VO(Member),它有三个属性,分别为:id(String)、name(String)和age(int)。

情景一:


    初始页面,Member对象会以id排序,现在name中保存的是英文名,需对name进行排序;

首先我们来看我们要用到的Java API中的一个接口Comparator

public   interface  Comparator < T >

比较函数强行对某些对象 collection 进行整体排序。可以将 Comparator 传递给 sort 方法(如 Collections.sort),从而允许在排序顺序上实现精确控制。还可以使用 Comparator 来控制某些数据结构(如 TreeSet 或 TreeMap)的顺序。

当且仅当对于一组元素 S 中的每个 e1 和 e2 而言,(compare((Object)e1, (Object)e2)==0) 与 e1.equals((Object)e2) 具有相等的布尔值时,Comparator c 强行对 S 进行的排序才叫做与等号一致 的排序。

 

也就是说,只要我们新建一个类用于排序,实现Comparator接口的compare()就可以了;

     public   int  compare(Object op1, Object op2) {
        Member memberOp1 
=  (Member) op1;
        Member memberOp2 
=  (Member) op2;

        
//  按姓名(英文)排序
         return  memberOp1.getName().compareTo(memberOp2.getName());
    }


然后在使用时通过调用Collections.sort()就可以了;

具体步骤如下:
1、新建一个工程Object排序,然后建三个包,一个为:com.coderdream.util,用于存放“比较工具类”;另一个为:com.coderdream.view,用于存放操作VO,另一个包名为:com.coderdream.service,存放操作VO的类,这里我写两个测试类,分别用于测试中英文。


代码1:

/*
 * Member.java 
 * 
 * Provider: CoderDream's Studio
 * 
 * History
 *   Date(DD/MM/YYYY)    Author          Description
 * ----------------------------------------------------------------------------
 *    2007/12/19        CoderDream          Created
 
*/
package  com.coderdream.view;

/**
 * discription: 操作對象VO
 * 
 * 
@author  CoderDream
 * 
 
*/
public   class  Member {

    
/**
     * ID
     
*/
    
private  String id;

    
/**
     * 名字
     
*/
    
private  String name;

    
/**
     * 年齡
     
*/
    
private   int  age;

    
/**
     * 
@param  name
     * 
@param  age
     
*/
    
public  Member(String id, String name,  int  age) {
        
this .id  =  id;
        
this .name  =  name;
        
this .age  =  age;
    }

    
/**
     * 
@return
     
*/
    
public  String getName() {
        
return  name;
    }

    
/**
     * 
@param  name
     
*/
    
public   void  setName(String name) {
        
this .name  =  name;
    }

    
/**
     * 
@return
     
*/
    
public   int  getAge() {
        
return  age;
    }

    
/**
     * 
@param  age
     
*/
    
public   void  setAge( int  age) {
        
this .age  =  age;
    }

    
/**
     * 
@return  the id
     
*/
    
public  String getId() {
        
return  id;
    }

    
/**
     * 
@param  id
     *            the id to set
     
*/
    
public   void  setId(String id) {
        
this .id  =  id;
    }

}

代码2:

/*
 * CompareName.java 
 * 
 * Provider: CoderDream's Studio
 * 
 * History
 *   Date(DD/MM/YYYY)    Author          Description
 * ----------------------------------------------------------------------------
 *    2007/12/19        CoderDream          Created
 
*/
package  com.coderdream.util;

import  java.util.Comparator;

import  com.coderdream.view.Member;

/**
 * discription:根據英文字母比較 
 *
 * 
@author  CoderDream
 *
 
*/
public   class  CompareName  implements  Comparator {
    
    
public   int  compare(Object op1, Object op2) {
        Member memberOp1 
=  (Member) op1;
        Member memberOp2 
=  (Member) op2;

        
//  按姓名(英文)排序
         return  memberOp1.getName().compareTo(memberOp2.getName());
    }
}

代码3:

/*
 * CompareAge.java 
 * 
 * Provider: CoderDream's Studio
 * 
 * History
 *   Date(DD/MM/YYYY)    Author          Description
 * ----------------------------------------------------------------------------
 *    2007/12/19        CoderDream          Created
 
*/
package  com.coderdream.util;

import  java.util.Comparator;
import  com.coderdream.view.Member;

/**
 * discription: 根據年齡比較,由小到大
 * 
 * 
@author  CoderDream
 *
 
*/
public   class  CompareAge  implements  Comparator {
    
    
public   int  compare(Object op1, Object op2) {
        Member memberOp1 
=  (Member) op1;
        Member memberOp2 
=  (Member) op2;

        
//  按 年齡 排序
         return  memberOp1.getAge()  <  memberOp2.getAge()  ?   0  :  1 ;
    }
}

代码4:

/*
 * Client1.java 
 * 
 * Provider: CoderDream's Studio
 * 
 * History
 *   Date(DD/MM/YYYY)    Author          Description
 * ----------------------------------------------------------------------------
 *    2007/12/19        CoderDream          Created
 
*/
package  com.coderdream.service;

import  java.util.ArrayList;
import  java.util.Collections;
import  java.util.List;
import  com.coderdream.util.CompareAge;
import  com.coderdream.util.CompareName;
import  com.coderdream.view.Member;

/**
 * discription:測試類1,按字母和年齡比較 
 *
 * 
@author  CoderDream
 *
 
*/
public   class  Client1 {

    
/**
     * 
@param  args
     
*/
    
public   static   void  main(String[] args) {
        
//  新建链表并加入元素
        List < Member >  members  =   new  ArrayList < Member > ();
        members.add(
new  Member( " 01 " " Andy " 20 ));
        members.add(
new  Member( " 02 " " Dell " 26 ));
        members.add(
new  Member( " 03 " " Felex " 24 ));
        members.add(
new  Member( " 04 " " Bill " 21 ));
        members.add(
new  Member( " 05 " " Cindy " 28 ));

        
//  输出排序后的链表
        System.out.println( " Original Data:  " );
        
for  (Member member : members) {
            System.out.println(
"    " +  member.getName()  +   " : "   +  member.getAge());
        }

        
//  按名字排序
        Collections.sort(members,  new  CompareName());
        System.out.println(
" Sort by Name:  " );
        
//  输出排序后的链表
         for  (Member member : members) {
            System.out.println(
"    "   +  member.getName()  +   " : "   +  member.getAge());
        }

        
//  按 年齡 排序
        Collections.sort(members,  new  CompareAge());
        System.out.println(
" Sort by Age: " );
        
//  输出排序后的链表
         for  (Member member : members) {
            System.out.println(
"    "   +  member.getName()  +   " : "   +  member.getAge());
        }
    }

}

运行结果:

Original Data: 
  Andy:
20
  Dell:
26
  Felex:
24
  Bill:
21
  Cindy:
28
Sort by Name: 
  Andy:
20
  Bill:
21
  Cindy:
28
  Dell:
26
  Felex:
24
Sort by Age:
  Andy:
20
  Bill:
21
  Felex:
24
  Dell:
26
  Cindy:
28


情景二:


    初始页面,Member对象会以id排序,现在name中保存的是中文名(字符集为GBK,包括简体中文和繁体中文),需对name进行排序;

     这里我们要用到SourceForge的pinyin4j项目的jar包,可以解决这个问题,pinyin4j的项目地址是: http://pinyin4j.sourceforge.net/ ,本文最后的源代码中已包含此Jar包。
     
     注意,由于这里要比较的是对象,所以我们实现接口:Comparator<Object> 
     这里我们会用到包中PinyinHelper类的toHanyuPinyinStringArray(char c)方法,该方法返回该字的汉语拼音数组:

        // 返回该字的汉语拼音数组,如“王”字返回:[wang2, wang4],说明该字有两种读法,分别为wang2,第二声,wang4,第四声
        String[] a  =  PinyinHelper.toHanyuPinyinStringArray(c);

代码5:

/*
 * CompareNamePinyin.java 
 * 
 * Provider: CoderDream's Studio
 * 
 * History
 *   Date(DD/MM/YYYY)    Author          Description
 * ----------------------------------------------------------------------------
 *    2007/12/19        CoderDream          Created
 
*/
package  com.coderdream.util;

import  java.util.Comparator;
import  net.sourceforge.pinyin4j.PinyinHelper;
import  com.coderdream.view.Member;


/**
 * discription:根據漢語拼音比較,第一個字相同再比較第二個字 
 *
 * 
@author  CoderDream
 *
 
*/
public   class  CompareNamePinyin  implements  Comparator < Object >  {
    
    
public   int  compare(Object obj1, Object obj2) {
        Member m1 
=  (Member)obj1;
        Member m2 
=  (Member)obj2;
        String o1 
=  m1.getName();
        String o2 
=  m2.getName();
        
        
for  ( int  i  =   0 ; i  <  o1.length()  &&  i  <  o2.length(); i ++ ) {
            
char  c1  =  o1.charAt(i);
            
char  c2  =  o2.charAt(i);

            String pinyin1 
=  pinyin(c1);
            String pinyin2 
=  pinyin(c2);

            
if  (pinyin1  !=   null   &&  pinyin2  !=   null ) {

                
if  ( ! pinyin1.equals(pinyin2)) {
                    
return  pinyin1.compareTo(pinyin2);
                }
            } 
else  {
                
if  (c1  !=  c2) {
                    
return  c1  -  c2;
                }
            }
        }
        
        
return  o1.length()  -  o2.length();
    }

    
/**
     * 字符的拼音,多音字就得到第一个拼音。不是汉字,就return null。
     * 
     * 
@param  c
     * 
@return
     
*/
    
private  String pinyin( char  c) {
        
// 返回该字的汉语拼音数字,如“王”字返回:[wang2, wang4]
        // 说明该字有两种读法,分别为wang2,第二声,wang4,第四声
        String[] a  =  PinyinHelper.toHanyuPinyinStringArray(c);
        
if  (a  ==   null ){
            
return   null ;
        }
        
return  a[ 0 ];
    }

}
代码6:
/*
 * Client2.java 
 * 
 * Provider: CoderDream's Studio
 * 
 * History
 *   Date(DD/MM/YYYY)    Author          Description
 * ----------------------------------------------------------------------------
 *    2007/12/19        CoderDream          Created
 
*/
package  com.coderdream.service;

import  java.util.ArrayList;
import  java.util.Collections;
import  java.util.List;
import  com.coderdream.util.CompareAge;
import  com.coderdream.util.CompareNamePinyin;
import  com.coderdream.view.Member;

/**
 * discription: 測試類2,按字母和年齡比較 
 *
 * 
@author  CoderDream
 *
 
*/
public   class  Client2 {

    
/**
     * 
@param  args
     
*/
    
public   static   void  main(String[] args) {
        
//  新建链表并加入元素
        List < Member >  members  =   new  ArrayList < Member > ();
        members.add(
new  Member( " 01 " " 王五 " 20 ));
        members.add(
new  Member( " 02 " " 劉六 " 26 ));
        members.add(
new  Member( " 03 " " 錢一 " 24 ));
        members.add(
new  Member( " 04 " " 趙二 " 21 ));
        members.add(
new  Member( " 05 " " 李四 " 29 ));
        members.add(
new  Member( " 06 " " 張三 " 28 ));
        members.add(
new  Member( " 07 " " 張七 " 25 ));

        
//  输出排序后的链表
        System.out.println( " Original Data:  " );
        
for  (Member member : members) {
            System.out.println(
"    "   +  member.getName()  +   " : "   +  member.getAge());
        }

        
//  按名字排序
        Collections.sort(members,  new  CompareNamePinyin());
        System.out.println(
" Sort by Name:  " );
        
//  输出排序后的链表
         for  (Member member : members) {
            System.out.println(
"    "   +  member.getName()  +   " : "   +  member.getAge());
        }

        
//  按 年齡 排序
        Collections.sort(members,  new  CompareAge());
        System.out.println(
" Sort by Age: " );
        
//  输出排序后的链表
         for  (Member member : members) {
            System.out.println(
"    "   +  member.getName()  +   " : "   +  member.getAge());
        }
    }

}
输出结果:
Original Data: 
  王五:
20
  劉六:
26
  錢一:
24
  趙二:
21
  李四:
29
  張三:
28
  張七:
25
Sort by Name: 
  李四:
29
  劉六:
26
  錢一:
24
  王五:
20
  張七:
25
  張三:
28
  趙二:
21
Sort by Age:
  王五:
20
  趙二:
21
  錢一:
24
  張七:
25
  劉六:
26
  張三:
28
  李四:
29

源代码(包含Jar包),可直接由eclipse导入

参考:
1、 中文排序 - 汉语拼音
2、 用匿名类实现Comparator实现链表排序的例子

你可能感兴趣的:(对象排序与按汉语拼音排序)