在項目開發中,經常會遇到一些排序的問題。
現在有一個操作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實現鏈表排序的例子
posted on 2007-12-19 16:07
CoderDream 閱讀(1702)
評論(0) 編輯 收藏 所屬分類:
經驗點滴