在项目开发中,经常会遇到一些排序的问题。
现在有一个操作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 阅读(1693)
评论(0) 编辑 收藏 所属分类:
经验点滴