Java核心技术之Comparator和Comparable在排序中的应用

最后更新于:2022-04-01 09:58:27

### 自定义的类User: ~~~ package com.example.testcomparator; public class User{ private String name; private int age; public User(String name, int age) { this.name = name; this.age = age; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String toString(){ return "name:"+name+"--age:"+age; } } ~~~ 当我们有一组User对象组合时,我们要对其中的User对象排序,优先对name排序,如果name一样,则再依据age排序。 ### 1.使用Comparator接口来排序: ~~~ package com.example.testcomparator; import java.util.Comparator; //先比较id,再比较age public class UserComparator implements Comparator<User>{ @Override public int compare(User user0, User user1) { // TODO Auto-generated method stub int flag = 0; flag = user0.getName().compareTo(user1.getName()); if(flag == 0) { // 如果id一样,比较年龄, 返回比较年龄结果 return user0.getAge() - user1.getAge(); } else { return flag; // 名字不一样, 返回比较id的结果. } } } ~~~ 排序方法,我们分别对List和数组来分别排序: (1)List排序: ~~~ List userList = new ArrayList<User>(); userList.add(new User("a",5)); userList.add(new User("c",6)); userList.add(new User("a",4)); userList.add(new User("b",2)); userList.add(new User("b",3)); userList.add(new User("c",7)); for(int i = 0;i<userList.size();i++){ Log.i(TAG, "排序前:"+userList.get(i)); } Collections.sort(userList, new UserComparator()); for(int i = 0;i<userList.size();i++){ Log.i(TAG, "排序后:"+userList.get(i)); } ~~~ (2)对数组排序: ~~~ User[] userArray = new User[]{ new User("a", 5), new User("c", 6), new User("a", 4), new User("b", 2), new User("b", 3), new User("c", 7)}; for(int i = 0;i<userArray.length;i++){ Log.i(TAG, "排序前:"+userArray[i]); } Arrays.sort(userArray,new UserComparator()); for(int i = 0;i<userArray.length;i++){ Log.i(TAG, "排序后:"+userArray[i]); } ~~~ 输出结果: 排序前:name:a--age:5 排序前:name:c--age:6 排序前:name:a--age:4 排序前:name:b--age:2 排序前:name:b--age:3 排序前:name:c--age:7 排序后:name:a--age:4 排序后:name:a--age:5 排序后:name:b--age:2 排序后:name:b--age:3 排序后:name:c--age:6 排序后:name:c--age:7 ### 2.使用Comparable接口来排序: 先要改造User类: ~~~ package com.example.testcomparator; public class User implements Comparable<Object>{ private String name; private int age; public User(String name, int age) { this.name = name; this.age = age; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String toString(){ return "name:"+name+"--age:"+age; } @Override //先比较id,id相同后再比较age public int compareTo(Object object) { // TODO Auto-generated method stub int flag = 0; flag = name.compareTo(((User)object).getName()); // 使用字符串的比较 if(flag == 0) { // 如果id一样,比较年龄, 返回比较年龄结果 return age - ((User)object).getAge(); } else { return flag; // 名字不一样, 返回比较id的结果. } } } ~~~ (1)List排序: ~~~ List userList = new ArrayList<User>(); userList.add(new User("a",5)); userList.add(new User("c",6)); userList.add(new User("a",4)); userList.add(new User("b",2)); userList.add(new User("b",3)); userList.add(new User("c",7)); for(int i = 0;i<userList.size();i++){ Log.i(TAG, "排序前:"+userList.get(i)); } Collections.sort(userList); for(int i = 0;i<userList.size();i++){ Log.i(TAG, "排序后:"+userList.get(i)); } ~~~ (2)对数组排序: ~~~ User[] userArray = new User[]{ new User("a", 5), new User("c", 6), new User("a", 4), new User("b", 2), new User("b", 3), new User("c", 7)}; for(int i = 0;i<userArray.length;i++){ Log.i(TAG, "排序前:"+userArray[i]); } Arrays.sort(userArray); for(int i = 0;i<userArray.length;i++){ Log.i(TAG, "排序后:"+userArray[i]); } ~~~ 输出结果: 排序前:name:a--age:5 排序前:name:c--age:6 排序前:name:a--age:4 排序前:name:b--age:2 排序前:name:b--age:3 排序前:name:c--age:7 排序后:name:a--age:4 排序后:name:a--age:5 排序后:name:b--age:2 排序后:name:b--age:3 排序后:name:c--age:6 排序后:name:c--age:7 ### 3.总结: comparable   Comparator 都是用来实现集合中的排序的。 Comparable是在集合内部定义的方法实现的排序, Comparator是在集合外部实现的排序, 所以,如想实现排序,就需要在集合外定义Comparator接口的方法compare()或在集合内实现Comparable接口的方法compareTo()。 两种方法各有优劣:  用Comparable 简单, 只要实现Comparable 接口的对象直接就成为一个可以比较的对象,但是需要修改源代码。 用Comparator 的好处是不需要修改源代码, 而是另外实现一个比较器, 当某个自定义的对象需要作比较的时候,把比较器和对象一起传递过去就可以比大小了,  并且在Comparator 里面用户可以自己实现复杂的可以通用的逻辑,使其可以匹配一些比较简单的对象,那样就可以节省很多重复劳动了。 用 Comparator 是策略模式(strategy design pattern),就是不改变对象自身,而用一个策略对象(strategy object)来改变它的行为,所以,我们推荐使用Comparator. ### 4.参考资料: 1.Comparator和Comparable在排序中的应用 [http://www.blogjava.net/fastunit/archive/2008/04/08/191533.html](http://www.blogjava.net/fastunit/archive/2008/04/08/191533.html) 2.Java中,如果想要排序,实现Comparator接口 //与Comparable 的区别? [http://zhidao.baidu.com/link?url=54BbyjAWPv5pG3l9c_ww0-4vPPdQSZ6FZ6u-yJAh52bJwXRRyTPN9iUUvpUYzKOMBLhl80Po2qfBI4Vipansh_](http://zhidao.baidu.com/link?url=54BbyjAWPv5pG3l9c_ww0-4vPPdQSZ6FZ6u-yJAh52bJwXRRyTPN9iUUvpUYzKOMBLhl80Po2qfBI4Vipansh_)
';