现在的位置: 首页 > 综合 > 正文

读JSE源码(二):Comparable接口和Comparator接口

2017年12月15日 ⁄ 综合 ⁄ 共 3116字 ⁄ 字号 评论关闭

目录

1 介绍

2 Comparable接口

3 Comparator接口

4 总结

 

1 介绍

      有这样2个人,一个人光头,一个人有黑色头发,现在不允许染发,只允许光头的带假发,理由是有头发的人没有必要再带假发,那么谁可以有多种颜色的头发?在这种情况下,有头发的人,因为他的头发和自身绑定在一起,是无法在换头发的;而光头的头发(假发套)和其自身是不绑定的,可以根据自己喜欢换不同颜色的发套。有头发的人叫Comparable,光头不是孟飞,也不是乐嘉,叫Comparator。

 

 

    Comparable和Comparator是java中2个比较接口。Comparable是和具体类绑定的,我们称为“静态绑定”(如上图中有头发的人,头发是Comparable,头是具体的类)。而对于Comparator,具体的类在需要是可选择不同的Comparator绑定,是“动态绑定”(策略模式)(如上图中光头的人,假发是Comparator,头是具体的类,可根据需要选择不同的假发)。两者相比,Comparator比Comparable灵活,而且具体类可以在需要时选择不同的Comparator。

2 Comparable接口

    java.lang. Comparable接口定义类的自然顺序,实现该接口的类就可以按这种方式排序。Comparable只包含一个方法:

public interface Comparable<T> { 

    public int compareTo(T o); 

} 
int compareTo(Object o): 比较当前实例对象与对象o,如果位于对象o之前,返回负值,如果两个对象在排序中位置相同,则返回0,如果位于对象o后面,则返回正值。String类实现了Comparable接口。
    需要比较或排序的对象,可以选择实现Comparable接口,自定义比较算法
例子
import java.util.Arrays;

/** 
 * @version 1.0
 * @date    2012-11-15 下午2:25:27 
 * @fuction  实现Comparable接口 (先按序号比较,序号相等在比较姓名) */

	public	class Student implements Comparable
	{
		//学号
		int num;
		//姓名
		String name;
		
		//constructor
		public Student(int num,String name)
		{
			this.num=num;
			this.name=name;
		}

		//重写java.lang中的接口Comparable的方法compareTo,定制比较的规则.但必须遵守比较规则(比较结果大返回正数,相等返回0,小返回负数)
		public int compareTo(Object o) {
			Student s=(Student)o;
			int result=num>s.num ? 1:(num==s.num ? 0: -1);
			//学号相等时,按名字排序
			if(0==result)
			{
				//利用String的compareTo方法进行字符的比较
			    result=name.compareTo(s.name);
			}
			return result;
		}

		@Override
		public String toString() {
			return "Student [num=" + num + ", name=" + name + "]";
		}
		
		
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Student[] test=new Student[]{new Student(2, "wangwu"),
				                     new Student(1, "lisi"),
				                     new Student(1, "goudan") };
		//排序
		Arrays.sort(test);
		
		//打印
		for(int i=0;i<test.length;i++)
		{
			System.out.println(test[i]);
			
		}
		
		//搜索姓名为“wangwu”的学生   
        int index=Arrays.binarySearch(test,new Student(2,"wangwu")); 
        System.out.println("查找的学生在数组中的位置:"+index);   
	}

}

3 Comparator接口

 java.util.Comparator接口只包含2个方法

int compare(T o1, T o2);
boolean equals(Object obj);

int compare(T o1, T o2);比较用来排序的两个参数。 

boolean equals(Object obj);指示是否其他对象“等于”此 Comparator。

实现了compare接口的类具体的实现是在compare方法中自定义比较算法,然后将Comparator对象(实现了java.util.Comparator接口的对象)作为一个参数传递给欲比较或排序对象collection的某些排序方法。某些排序方法指的是能够接受java.util.Comparator参数的方法,比如:java.util. Arrays的public static void sort(Object[] a, Comparator c)和Collections的sort方法。

例子

import java.util.Arrays;
import java.util.Comparator;

/**
 * @version 1.0
 * @date 2012-11-15 下午11:21:09
 * @fuction 实现Comparator接口的比较算法
 *按学号排序 先按学号排序,学号相等时,按姓名排序 o1>o2返回1,o1=o2返回0,o1>o2返回-1
 */

public class ByNumComparator implements Comparator {

	public int compare(Object o1, Object o2) {
		Student s1 = (Student) o1;
		Student s2 = (Student) o2;
		// 按学号排序
		int result = s1.num > s2.num ? 1 : (s1.num == s2.num ? 0 : -1);
		// 学号相等时,按名字排序
		if (result == 0) {
			int copmpareName=s1.name.compareTo(s2.name);
		//利用String的compareTo方法进行字符的比较  
		   if(copmpareName>0)
			result=1;
		   else if (copmpareName==0)
			result=0;
		   else
			result=-1;
		}

		return result;
	}

	public static void main(String[] args) {
		Student[] test = new Student[] { new Student(2, "wangwu"),
				new Student(1, "lisi"), new Student(1, "goudan") };
		// 排序
		Arrays.sort(test, new ByNumComparator());

		// 打印
		System.out.println("排序之后");
		for (int i = 0; i < test.length; i++) {
			System.out.println(test[i]);

		}

	}

}

输出结果:

排序之后
Student [num=1, name=goudan]
Student [num=1, name=lisi]
Student [num=2, name=wangwu]

4 总结

       一般在对对象进行比较或排序时,需要对象实现Comparable接口或者在使用排序方法(比如Arrays的sort)方法时,传入实现了Comparator接口的类的对象。

 

 

抱歉!评论已关闭.