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_)