本篇文章既是作为Java Comparable and Comparator 的说明,也是作为Strategy Design Pattern(策略模式)的一个典型例子。
Java对原生类型和包装类型均提供排序功能,不用自己去编写排序算法了。代码见下:
package dp.compare;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class SimpleSort {
/**
* This class shows how to sort primitive arrays, Wrapper classes Object
* Arrays
*
* @param args
*/
public static void main(String[] args) {
// sort primitives array like int array
int[] intArr = { 5, 9, 1, 10 };
Arrays.sort(intArr);
System.out.println(Arrays.toString(intArr));
// sorting String array
String[] strArr = { "A", "C", "B", "Z", "E" };
Arrays.sort(strArr);
System.out.println(Arrays.toString(strArr));
// sorting list of objects of Wrapper classes
List<String> strList = new ArrayList<String>();
strList.add("A");
strList.add("C");
strList.add("B");
strList.add("Z");
strList.add("E");
Collections.sort(strList);
for (String str : strList) {
System.out.print(" " + str);
}
System.out.println();
// sorting list of objects of Wrapper classes
List<String> strList2 = new ArrayList<String>();
strList2.add("Acc");
strList2.add("Cebs");
strList2.add("B_kkk");
strList2.add("Z76");
strList2.add("E77");
strList2.add("EA");
strList2.add("AcC");
Collections.sort(strList2);
for (String str : strList2) {
System.out.print(" " + str);
}
}
}
[1, 5, 9, 10]
[A, B, C, E, Z]
A B C E Z
AcC Acc B_kkk Cebs E77 EA Z76
当然,如果是自己定义的复杂的对象,则需要自己定义比较规则,以判断先后顺序,然后利用java.util.Arrays.sort方法对数组进行排序。也可以利用java.util.Collections.sort方法对列表对象进行排序。
而使用这两种排序方式的前提则是要实现 java.lang.Comparable 或者 java.util.Comparator 接口。通过实现这两个接口,才能给上面的两种sort方法提供合适比较算法,以确定排序的规则。
这样,也能够动态的,根据逻辑或者用户的选择,提供不同的排序算法,这恰好就是一个典型的Strategy Design Pattern(策略模式)。
代码如下:
package dp.compare;
import java.util.Comparator;
public class User implements Comparable<User> {
private String userName;
private int userId;
private int age;
private String realName;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getRealName() {
return realName;
}
public void setRealName(String realName) {
this.realName = realName;
}
public User(int userId, int age, String userName, String realName) {
this.userId = userId;
this.age = age;
this.userName = userName;
this.realName = realName;
}
@Override
public String toString() {
return "[User Id=" + this.userId + ", real name=" + this.realName
+ ", age=" + this.age + ", user name=" + this.userName + "]";
}
/*
* 默认的比较方法,用userId进行比较,返回负值表示<, 返回0表示=, 返回正值表示>
*/
@Override
public int compareTo(User user) {
return (this.userId - user.userId);
}
/*
* 用年龄进行比较的算法
*/
public static Comparator<User> UserComparatorByAge = new Comparator<User>() {
@Override
public int compare(User user1, User user2) {
return (int) (user1.getAge() - user2.getAge());
}
};
}
package dp.compare;
import java.util.Comparator;
public class UserComparatorByRealName implements Comparator<User> {
/*
* 使用用户真实名字进行对比的算法
*/
@Override
public int compare(User user1, User user2) {
return (user1.getRealName().compareTo(user2.getRealName()));
}
}
package dp.compare;
import java.util.Comparator;
public class UserComparatorByUserAgeAndUserName implements Comparator<User> {
/*
* 使用用户年龄和真实姓名进行对比的算法
*/
@Override
public int compare(User user1, User user2) {
int flat = (user1.getAge() - user2.getAge());
if (flat != 0) {
return flat;
} else {
return (user1.getUserName().compareTo(user2.getUserName()));
}
}
}
package dp.compare;
import java.util.Arrays;
public class Main {
public static void main(String args[]) {
// 创建模拟数据
User[] user1 = new User[8];
user1[0] = new User(1, 20, "001", "Wu Zhong");
user1[1] = new User(2, 40, "0011", "Lei Feng");
user1[2] = new User(3, 33, "2001", "Zhang Chen Chen");
user1[3] = new User(4, 22, "zhanglei001", "Su Dang Lei");
user1[4] = new User(21, 17, "76", "Jack Meng");
user1[5] = new User(33, 22, "andong1988", "Aady Long");
user1[6] = new User(9, 15, "31", "John Doe");
user1[7] = new User(45, 22, "jun@tao", "Hoo Jun Tao");
System.out.println("默认排序,用User类实现的 compareTo 方法中的算法进行排序");
Arrays.sort(user1);
for (int i = 0; i < 8; i++) {
System.out.println(user1[i].toString());
}
System.out.println("---------------------------");
System.out.println("使用Age字段进行排序");
Arrays.sort(user1, User.UserComparatorByAge);
for (int i = 0; i < 8; i++) {
System.out.println(user1[i].toString());
}
System.out.println("---------------------------");
System.out.println("使用RealName字段进行排序");
Arrays.sort(user1, new UserComparatorByRealName());
for (int i = 0; i < 8; i++) {
System.out.println(user1[i].toString());
}
System.out.println("---------------------------");
System.out.println("使用Age字段+UserName字段联合进行排序");
Arrays.sort(user1, new UserComparatorByUserAgeAndUserName());
for (int i = 0; i < 8; i++) {
System.out.println(user1[i].toString());
}
}
}
默认排序,用User类实现的 compareTo 方法中的算法进行排序
[User Id=1, real name=Wu Zhong, age=20, user name=001]
[User Id=2, real name=Lei Feng, age=40, user name=0011]
[User Id=3, real name=Zhang Chen Chen, age=33, user name=2001]
[User Id=4, real name=Su Dang Lei, age=22, user name=zhanglei001]
[User Id=9, real name=John Doe, age=15, user name=31]
[User Id=21, real name=Jack Meng, age=17, user name=76]
[User Id=33, real name=Aady Long, age=22, user name=andong1988]
[User Id=45, real name=Hoo Jun Tao, age=22, user name=jun@tao]
---------------------------
使用Age字段进行排序
[User Id=9, real name=John Doe, age=15, user name=31]
[User Id=21, real name=Jack Meng, age=17, user name=76]
[User Id=1, real name=Wu Zhong, age=20, user name=001]
[User Id=4, real name=Su Dang Lei, age=22, user name=zhanglei001]
[User Id=33, real name=Aady Long, age=22, user name=andong1988]
[User Id=45, real name=Hoo Jun Tao, age=22, user name=jun@tao]
[User Id=3, real name=Zhang Chen Chen, age=33, user name=2001]
[User Id=2, real name=Lei Feng, age=40, user name=0011]
---------------------------
使用RealName字段进行排序
[User Id=33, real name=Aady Long, age=22, user name=andong1988]
[User Id=45, real name=Hoo Jun Tao, age=22, user name=jun@tao]
[User Id=21, real name=Jack Meng, age=17, user name=76]
[User Id=9, real name=John Doe, age=15, user name=31]
[User Id=2, real name=Lei Feng, age=40, user name=0011]
[User Id=4, real name=Su Dang Lei, age=22, user name=zhanglei001]
[User Id=1, real name=Wu Zhong, age=20, user name=001]
[User Id=3, real name=Zhang Chen Chen, age=33, user name=2001]
---------------------------
使用Age字段+UserName字段联合进行排序
[User Id=9, real name=John Doe, age=15, user name=31]
[User Id=21, real name=Jack Meng, age=17, user name=76]
[User Id=1, real name=Wu Zhong, age=20, user name=001]
[User Id=33, real name=Aady Long, age=22, user name=andong1988]
[User Id=45, real name=Hoo Jun Tao, age=22, user name=jun@tao]
[User Id=4, real name=Su Dang Lei, age=22, user name=zhanglei001]
[User Id=3, real name=Zhang Chen Chen, age=33, user name=2001]
[User Id=2, real name=Lei Feng, age=40, user name=0011]
从上面的例子可以看出,通过选择不同的排序算法,可以得到不同的排序结果。这样,开发者可以指定好不同的排序算法,在运行时动态的进行选择,以实现最灵活的排序。
参考资料: http://www.journaldev.com/780/java-comparable-and-comparator-example-to-sort-objects