public class Test { public static void main(String[] args) { int a[] = {9, 5, 3, 7, 1, 10}; DataSorter.sort(a); DataSorter.p(a); } }
DataSort:
package com.cy.dp.strategy; public class DataSorter { /** * 选择排序法 * @param a public static void sort(int[] a) { int temp; for(int i=0; i<a.length; i++){ for(int j=i+1; j<a.length; j++){ if(a[i]>a[j]){ temp = a[i]; a[i] = a[j]; a[j] = temp; } } } } */ /** * 冒泡排序法 * @param a */ public static void sort(int[] a) { int temp; for(int i=a.length; i>0; i--){ for(int j=0; j<i-1; j++){ if(a[j]>a[j+1]){ temp = a[j]; a[j] = a[j+1]; a[j+1] = temp; } } } } public static void p(int[] a) { for(int i=0; i<a.length; i++){ System.out.print(a[i] + " "); } System.out.println(); } }
但是上面有个问题:
sort方法里面现在只能排序int类型的;
如果我想对于float类型进行排序,怎么办?--可以重载方法sort(float[] a);
如果想对于double类型的进行排序,怎么办?--再重载一个double参数的;
因为sort方法里面a[j]和a[j+1]的int类型的,能直接比较,这还好办,但是如果现在想DataSorter对猫、狗、Car、等等...进行排序,怎么办?
//实现这个接口的类,表示是可以比较的 public interface Comparable { public int compareTo(Object o); }
DataSort可以排序任何类(该类实现Comparable接口),打印任何类;
写完一次排序方法,再也不用改变了;
package com.cy.dp.strategy; public class DataSorter { /** * 冒泡排序法,排序任何类型,Object类型 * 假设Object[]里面对象都实现了Comparable接口,都是可以比较大小的; * @param a */ public static void sort(Object[] a) { Object temp; 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) > 0){ temp = a[j]; a[j] = a[j+1]; a[j+1] = temp; } } } } public static void p(Object[] a) { for(int i=0; i<a.length; i++){ System.out.print(a[i] + " "); } System.out.println(); } }
Cat实现Compareble接口:
package com.cy.dp.strategy; public class Cat implements Comparable{ 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 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; //简单写法,如果o不是cat,表示出错;实际要抛异常 } @Override public String toString() { return height + "|" + weight; } }
Dog实现Comparable接口:
package com.cy.dp.strategy; public class Dog implements Comparable{ private int food; public Dog(int food) { super(); this.food = food; } public int getFood() { return food; } public void setFood(int food) { this.food = food; } //对狗按照饭量大小进行排序 @Override public int compareTo(Object o) { Dog d = (Dog) o; if(this.food > d.getFood()) return 1; else if(this.food < d.getFood()) return -1; else return 0; } @Override public String toString() { return "Dog [food=" + food + "]"; } }
测试:
public class Test { public static void main(String[] args) { Cat a[] = {new Cat(5,5), new Cat(3,3), new Cat(1,1)}; DataSorter.sort(a); DataSorter.p(a); Dog d[] = {new Dog(3), new Dog(1), new Dog(5), new Dog(4)}; DataSorter.sort(d); DataSorter.p(d); } }
输出
1|1 3|3 5|5
Dog [food=1] Dog [food=3] Dog [food=4] Dog [food=5]
现在DataSort类可以对任何实现Comparable的类进行排序了,但是上面还是存在问题:
当前比较猫的大小的时候,只是根据猫的height,假如哪天要根据猫的weight、或者胡子的长度,或者别的来比较大小呢?怎么办?
也就是说现在Cat等实现的compareTo方法只能有一种实现,当还有其他不确定的实现时,这时候该怎么设计?
//比较器 public interface Comparator { int compare(Object o1, Object o2); }
猫的高度比较器:
//两只猫之间根据高度比较大小的 比较器 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; else return 0; } }
猫的重量比较器:
//两只猫之间根据重量比较大小的 比较器 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.getWeight() < c2.getWeight()) return 1; else return 0; } }
Cat类下面compareTo方法交给具体的比较器来实现:
package com.cy.dp.strategy; public class Cat implements Comparable{ private int height; private int weight; //默认是高度的比较器 //private Comparator comparator = new CatHeightComparator(); private Comparator comparator = new CatWeightComparator(); public Cat(int height, int weight) { super(); this.height = height; this.weight = weight; } public Comparator getComparator() { return comparator; } public void setComparator(Comparator comparator) { this.comparator = comparator; } 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 int compareTo(Object o) { return comparator.compare(this, o); } @Override public String toString() { return height + "|" + weight; } }
测试程序:
public class Test { public static void main(String[] args) { Cat a[] = {new Cat(5,5), new Cat(3,3), new Cat(1,1)}; //Dog a[] = {new Dog(3), new Dog(1), new Dog(5), new Dog(4)}; DataSorter.sort(a); DataSorter.p(a); } }
输出:5|5 3|3 1|1
4.看看JDK是怎么做的:我们使用jdk里面的Comparable接口、Comparator接口:
Cat:
package com.cy.dp.strategy; public class Cat implements java.lang.Comparable<Cat>{ private int height; private int weight; //默认是高度的比较器 private java.util.Comparator<Cat> comparator = new CatHeightComparator(); public Cat(int height, int weight) { super(); this.height = height; this.weight = weight; } public java.util.Comparator<Cat> getComparator() { return comparator; } public void setComparator(java.util.Comparator<Cat> comparator) { this.comparator = comparator; } 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 int compareTo(Cat o) { return comparator.compare(this, o); } @Override public String toString() { return height + "|" + weight; } }
根据高度的比较器CatHeightComparator:
//两只猫之间根据高度比较大小的 比较器 public class CatHeightComparator implements java.util.Comparator<Cat> { @Override public int compare(Cat c1, Cat c2) { if(c1.getHeight()>c2.getHeight()) return 1; else if(c1.getHeight() < c2.getHeight()) return -1; else return 0; } }
DataSort也改一下,就是使用java.lang.Comparable,其他不变:
package com.cy.dp.strategy; import java.lang.Comparable; public class DataSorter { /** * 冒泡排序法,排序任何类型,Object类型 * 假设Object[]里面对象都实现了Comparable接口,都是可以比较大小的; * @param a */ public static void sort(Object[] a) { Object temp; 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) > 0){ temp = a[j]; a[j] = a[j+1]; a[j+1] = temp; } } } } public static void p(Object[] a) { for(int i=0; i<a.length; i++){ System.out.print(a[i] + " "); } System.out.println(); } }
测试代码:
public class Test { public static void main(String[] args) { Cat a[] = {new Cat(5,5), new Cat(3,3), new Cat(1,1)}; //Dog a[] = {new Dog(3), new Dog(1), new Dog(5), new Dog(4)}; DataSorter.sort(a); DataSorter.p(a); } }
输出:1|1 3|3 5|5
完美和JDK融合;基本模拟了JDK里面的Comparable接口和Comparator接口;
5.而且其实不用自己写DataSort,用Arrays就行了:
public static void main(String[] args) { Cat a[] = {new Cat(5,5), new Cat(3,3), new Cat(1,1)}; //Dog a[] = {new Dog(3), new Dog(1), new Dog(5), new Dog(4)}; //DataSorter.sort(a); java.util.Arrays.sort(a); //Arrays.sort(Object[] a) 注:a必须实现Comparable接口 DataSorter.p(a); }
也可以:
public static void main(String[] args) { Cat a[] = {new Cat(5,5), new Cat(3,3), new Cat(1,1)}; //Dog a[] = {new Dog(3), new Dog(1), new Dog(5), new Dog(4)}; //DataSorter.sort(a); //java.util.Arrays.sort(a); java.util.Arrays.sort(a, new java.util.Comparator<Cat>(){ @Override public int compare(Cat o1, Cat o2) { return o1.getHeight()>o2.getHeight()?1 :o1.getHeight()<o2.getHeight()?-1 :0; } }); DataSorter.p(a); }
小结:
策略模式就是说,当我进行比较大小的时候,我定义一个策略的比较器,然后由具体的比较策略来决定谁大谁小;
使用例子,比如:
1.封装一下商场的打折策略;
周六打折,过年打折,两种加在一块就打折,等等。所以打折策略最好不要写死它,因为将来可能有不能确定的各种各样的打折策略;所以最好把打折策略定义成一个可以扩展的内容;这就是策略模式;
2.封装一下坦克的发射炮弹的策略;
有的时候打一发,有的时候打多发,等等,具体由我发射炮弹的策略决定;