本篇文章既是作为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 ListstrList = new ArrayList (); 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 strList2 = new ArrayList (); 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{ 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 UserComparatorByAge = new Comparator () { @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{ /* * 使用用户真实名字进行对比的算法 */ @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{ /* * 使用用户年龄和真实姓名进行对比的算法 */ @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