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

x33g5p2x  于2021-03-13 发布在 Java  
字(4.4k)|赞(0)|评价(0)|浏览(526)

自定义的类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

2.Java中,如果想要排序,实现Comparator接口 //与Comparable 的区别?

http://zhidao.baidu.com/link?url=54BbyjAWPv5pG3l9c_ww0-4vPPdQSZ6FZ6u-yJAh52bJwXRRyTPN9iUUvpUYzKOMBLhl80Po2qfBI4Vipansh_

下一篇:容器

相关文章