Comparable&Comparator

Comparable
Comparable 此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。对象本身就已经支持自比较所需要实现的接口(如 String、Integer 自己就可以完成比较大小操作)。

Comparator
如果一个类不能实现Comparable接口,那么我们自己可以提供Comparator的排序,如果你不喜欢缺省的Comparator行为,照样可以编写自己的Comparator。

策略模式:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

之所以要谈到策略模式,就是因为Comparator接口其实就是一种策略模式的实践。实现Comparator接口的类必然就会实现一个compare(Object o1, Object o2)的方法,而这个方法就是算法中的一部分,所有使用了compare方法的类都不会关心compare是如何工作的,只关心他的返回值,这也是面向对象中著名的封装特性。

下面模拟java中comparable和comparator的实现:

首先编写Comparable接口:

package com.lcq.strategy;

/**
 * 创建比较接口
 * @author lcq
 *
 */
public interface Comparable {
	public int compareTo(Object o);
}

然后编写Comparator接口:

package com.lcq.strategy;

public interface Comparator {
	int compare(Object o1, Object o2);
}

编写排序类DataSorter:

package com.lcq.strategy;

public class DataSorter {

	/**
	 * 编写冒泡排序方法
	 * 
	 * @param a
	 */
	public static void sort(int[] a) {
		for (int i = a.length; i > 0; i--) {
			for (int j = 0; j < i - 1; j++) {
				if (a[j] > a[j + 1]) {
					swap(a, j, j + 1);
				}
			}

		}

	}

	/**
	 * 交换两个数的值
	 * 
	 * @param a
	 * @param x
	 * @param y
	 */
	private static void swap(int[] a, int x, int y) {
		int temp;
		temp = a[x];
		a[x] = a[y];
		a[y] = temp;

	}

	/**
	 * 打印出数组的值
	 * 
	 * @param a
	 */
	public static void print(int[] a) {
		for (int i = 0; i < a.length; i++) {
			System.out.print(a[i] + " ");
		}

	}
	/**
	 * 打印出数组的值
	 * 
	 * @param a
	 */
	public static void print(Object[] a) {
		for (int i = 0; i < a.length; i++) {
			System.out.print(a[i] + " ");
		}

	}

	/**
	 * 编写可以对任意对象进行排序的方法
	 * @param a
	 */
	public static void sort(Object[] a) {
		for (int i = a.length; i > 0; i--) {
			for (int j = 0; j < i - 1; j++) {
				Comparable o1 = (Comparable) a[j];
				Comparable o2 = (Comparable) a[j + 1];
				if (o1.compareTo(o2) == 1) {
					swap(a, j, j + 1);
				}
			}

		}

	}

	/**
	 * 交换任意对象
	 * @param a
	 * @param x
	 * @param y
	 */
	private static void swap(Object[] a, int x, int y) {
		Object temp;
		temp = a[x];
		a[x] = a[y];
		a[y] = temp;
	}

}

为了测试,我们编写Cat类,在Cat类中继承Comparable接口重写compareTo方法:

package com.lcq.strategy;

/**
 * 创建测试的工具类,并且继承Comparable接口,实现compareTo方法
 * 
 * @author lcq
 * 
 */

public class Cat implements Comparable {
	private int height;
	private int weight;
    private Comparator comparator = new CatHeightComparator();
    
	public Comparator getComparator() {
		return comparator;
	}

	public void setComparator(Comparator comparator) {
		this.comparator = comparator;
	}

	public Cat(int height, int weight) {
		super();
		this.height = height;
		this.weight = weight;
	}

	public int getHeight() {
		return height;
	}

	public void setHeight(int height) {
		this.height = height;
	}

	public int getWeight() {
		return weight;
	}

	public void setWeight(int weight) {
		this.weight = weight;
	}

	@Override
	public String toString() {
		return this.getHeight() + "|" + this.getWeight();
	}

	@Override
	public int compareTo(Object o) {
		// if (o instanceof Cat) {
		// Cat c = (Cat) o;
		// if (this.getHeight() > c.getHeight())
		// return 1;
		// else if (this.getHeight() < c.getHeight())
		// return -1;
		// else
		// return 0;
		// }
		// return -100;
		return this.comparator.compare(this, o);
	}

}

编写Cat类的比较器类CatHeightComparator:

package com.lcq.strategy;

public class CatHeightComparator implements Comparator {

	@Override
	public int compare(Object o1, Object o2) {
		Cat c1 = (Cat)o1;
		Cat c2 = (Cat)o2;
		if(c1.getHeight() > c2.getHeight()) return 1;
		else if(c1.getHeight() < c2.getHeight()) return -1;
		return 0;
	}

}

最后是测试类Test:

package com.lcq.strategy;

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

//		int[] a = {4,5,9,2,3,7};
		Cat[] a = {new Cat(1,1),new Cat(4,4),new Cat(2,2)};
		DataSorter.sort(a);
		DataSorter.print(a);
		
	}

}

现在想实现Cat的反序排列,只需要再实现一个Comparator接口,反序比较Cat即可。

参考资料:

http://blog.csdn.net/lyjiau/article/details/17043285

http://blog.csdn.net/liuchangqing123/article/details/7345588

http://blog.csdn.net/ht99582/article/details/12687487

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值