文章出处:http://blog.csdn.net/scarthr/article/details/42398047
1. 自己实现排序打印方法
我们先来写这样一个类,它提供了给int数组排序和打印的方法:
package com.thr.strategy;
public class DataSorter {
public static void sort(int[] array) {
for (int i = array.length - 1; i >= 0; i--) {
for (int j = 0; j < i; j++) {
if (array[j] > array[j + 1]) {
swap(array, j, j + 1);
}
}
}
}
private static void swap(int[] array, int x, int y) {
int temp = array[x];
array[x] = array[y];
array[y] = temp;
}
public static void pritn(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
如果我们需要的是对double型数组排序呢?可以,粘贴复制一份,使用重载就行了。要是float呢?一样。
如果是这样一个自己定义的类呢?
package com.thr.strategy;
public class Cat {
private int height;
private int weight;
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 "Cat [height=" + height + ", weight=" + weight + "]";
}
}
要是用height来比较的话,增加DataSorter代码: public static void sort(Cat[] array) {
for (int i = array.length - 1; i >= 0; i--) {
for (int j = 0; j < i; j++) {
if (array[j].getHeight() > array[j + 1].getHeight()) {
swap(array, j, j + 1);
}
}
}
}
private static void swap(Cat[] array, int x, int y) {
Cat temp = array[x];
array[x] = array[y];
array[y] = temp;
}
public static void pritn(Cat[] array) {
for (int i = 0; i < array.length; i++) {
System.out.println(array[i].toString());
}
}
那么问题就来了,如果将来要拿dog来排序,再后来pig也需要排序等等。。。这样做是不是不妥了呢?这是我们就要考虑使用接口了(当程序想要扩展是,第一个应当想到多态)!
2. 创建接口Comparable
于是我们定义这样一个接口,它用来规定类之间比较的规则:
package com.thr.strategy;
public interface Comparable {
int compareTo(Object o);
}
将Cat类实现Comparable接口,这次我们用体重比较大小,增加方法compareTo:
@Override
public int compareTo(Object o) {
if (o instanceof Cat) {
Cat c = (Cat) o;
if (getWeight() > c.getWeight()) {
return 1;
} else if (getWeight() < c.getWeight()) {
return -1;
} else {
return 0;
}
} else {
return -2;
}
}
最后修改DataSorter类:package com.thr.strategy;
public class DataSorter {
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);
}
}
}
}
private static void swap(Object[] a, int x, int y) {
Object temp = a[x];
a[x] = a[y];
a[y] = temp;
}
public static void sort(int[] array) {
for (int i = array.length - 1; i >= 0; i--) {
for (int j = 0; j < i; j++) {
if (array[j] > array[j + 1]) {
swap(array, j, j + 1);
}
}
}
}
private static void swap(int[] array, int x, int y) {
int temp = array[x];
array[x] = array[y];
array[y] = temp;
}
public static void pritn(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
public static void pritn(Object[] array) {
for (int i = 0; i < array.length; i++) {
System.out.println(array[i].toString());
}
}
}
完成Cat的比较,并且任何类只需实现Comparable接口,即可调用DataSorter的sort方法进行排序。如果以后我们需要对Cat的并不是体重或者身高来比较大小时,我们还是得需要重构Cat类,那么有什么办法可以解决呢?
3. 创建比较器Comparator
我们需要自己去指定一个类的比较规则,并且随时可以更换,这时候比较器就出来了,我们定义一个Comparator接口:
package com.thr.strategy;
public interface Comparator {
int compare(Object o1, Object o2);
}
然后定义两个比较器,都实现Comparator接口,分别用身高和体重来比较:package com.thr.strategy;
public class CatHeightComparator implements java.util.Comparator<Cat> {
@Override
public int compare(Cat o1, Cat o2) {
Cat c1 = (Cat) o1;
Cat c2 = (Cat) o2;
if (c1.getHeight() > c2.getHeight()) {
return 1;
} else if (c1.getHeight() < c2.getHeight()) {
return -1;
} else {
return 0;
}
}
}
package com.thr.strategy;
public class CatWeightComparator implements Comparator {
@Override
public int compare(Object o1, Object o2) {
Cat c1 = (Cat) o1;
Cat c2 = (Cat) o2;
if (c1.getWeight() > c2.getWeight()) {
return -1;
} else if (c1.getHeight() < c2.getHeight()) {
return 1;
} else {
return 0;
}
}
}
这是我们修改Cat类,增加成员变量Comparator,设置set和get方法,默认给比较器设成CatHeightComparator,修改Comparable接口实现:
@Override
public int compareTo(Object o) {
return comparator.compare(this, o);
}
这时候,如果需要使用体重来比较大小时,只需要更换比较器就行了。
4. 使用系统的带有泛型的Comparator和Comparable
至此,我们已经自己写好了jdk本来就提供好了的Comparator和Comparable。jdk所提供的Comparator和Comparable还有一个泛型的概念,我们现在使用jdk的这两个接口来实现我们的排序,使用泛型的好处就是不用在程序中强制转换了。修改使用jdk的Comparator和Comparable后运行,没问题。
另外,jdk的Arrays类有一个静态方法,已经帮我们实现了排序的算法,只需要我们传的数组实现了Comparable接口就可以了。
总结一下策略模式:当进行比较大小的时候,定义一个策略的比较器,由具体的比较策略来决定谁大谁小。