设计模式 策略模式
里面涉及泛型,多态 的知识,如果看不懂的话,最好先看看泛型,如果对多态有很好的理解的话,学起来还是比较简单的
再具体讲解策略模式之前,我们先看一个比较简单的实例
先创建一个Comparable接口,便于让实现类实现方法compareTo()
Comparable.java
package 策略模式;
public interface Comparable<T> {
int compareTo(T t);
}
在写几个实现类,里面有(构造器,实现接口的方法,重写toString(),成员变量)
Dog.java
package 策略模式;
public class Dog implements Comparable<Dog>{
int food;
@Override
public String toString() {
return "Dog{" +
"food=" + food +
'}';
}
@Override
public int compareTo(Dog dog) {
if(this.food<dog.food) return -1;
else if (this.food>dog.food) return 1;
return 0;
}
public Dog(int food) {
this.food = food;
}
}
Cat.java
package 策略模式;
public class Cat implements Comparable<Cat>{
int weight,height;
@Override
public String toString() {
return "Cat{" +
"weight=" + weight +
", height=" + height +
'}';
}
public Cat(int weight, int height) {
this.weight = weight;
this.height = height;
}
@Override
public int compareTo(Cat c){
if(this.weight<c.weight) return -1;
else if(this.weight>c.weight) return 1;
return 0;
}
}
再写一个比较的方法
Sorter.java
package 策略模式;
public class Sorter {
public static void sort(Comparable[] a){
for(int i=0;i<a.length-1;i++){
int min=i;
for (int j = i+1; j < a.length; j++) {
min=a[j].compareTo(a[min])==-1?j:min;
}
swap(a,i,min);
}
}
static void swap(Comparable[] a, int i, int min) {
Comparable temp=a[i];
a[i]=a[min];
a[min]=temp;
}
}
再写一个测试方法
Main.java
package 策略模式;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
Cat[] a={new Cat(3,3),new Cat(4,4),new Cat(9,9),new Cat(1,1)};
//Dog[] a={new Dog(10),new Dog(5),new Dog(7)};
Sorter sorter=new Sorter();
sorter.sort(a);
System.out.println(Arrays.toString(a));
}
}
这是一道开胃菜,从里面我们可以得知,如果实现类中只有一个成员变量,我们可以轻松的比较,
但是成员变量一多,而实现类只能有一个compareTo()方法,如果想用其他的成员变量比较对象,就会变得比较困难,所以有了下一个方法
还是先写一个接口Comparator.java
package 策略模式;
/*
*
* 比较器
* 比较策略
* */
public interface Comparator<T> {
int compareTo(T o1,T o2);
}
Dog.java,和Cat.java就不在这里再写一遍了,如果你忘了,可以翻到上面再看一看
在这里我们单独写比较器,实现Comparator.java接口
我们可以为每一个成员变量写一个比较器
DogComparator.java
package 策略模式;
public class DogComparator implements Comparator<Dog>{
@Override
public int compareTo(Dog o1, Dog o2) {
if(o1.food<o2.food) return -1;
else if (o1.food>o2.food) return 1;
else return 0;
}
}
CatWeightComparator.java
package 策略模式;
public class CatWeightComparator implements Comparator<Cat>{
@Override
public int compareTo(Cat o1, Cat o2) {
if(o1.weight<o2.weight) return -1;
else if (o1.weight>o2.weight) return 1;
else return 0;
}
}
CatHeightComparator.java
package 策略模式;
public class CatHeightComparator implements Comparator<Cat>{
@Override
public int compareTo(Cat o1, Cat o2) {
if(o1.height<o2.height) return -1;
else if (o1.height>o2.height) return 1;
else return 0;
}
}
再写一个新的比较方法
Sorter2.java
package 策略模式;
public class Sorter2<T> {
public void sort(T[] a,Comparator<T> comparator){
for(int i=0;i<a.length-1;i++){
int min=i;
for (int j = i+1; j < a.length; j++) {
min=comparator.compareTo(a[j],a[min])==-1?j:min;
}
swap(a,i,min);
}
}
void swap(T[] a, int i, int min) {
T temp=a[i];
a[i]=a[min];
a[min]=temp;
}
}
最后进行测试
Main.java
package 策略模式;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
// Cat[] a={new Cat(3,3),new Cat(4,4),new Cat(9,9),new Cat(1,1)};
// Dog[] a={new Dog(10),new Dog(5),new Dog(7)};
// Sorter sorter=new Sorter();
// sorter.sort(a);
// System.out.println(Arrays.toString(a));
Dog[] a={new Dog(10),new Dog(5),new Dog(7)};
Sorter2<Dog> sorter2=new Sorter2<>();
sorter2.sort(a,new DogComparator());
System.out.println(Arrays.toString(a));
}
}
总结:
里面涉及的Comparable<>和Comparator实际上是重写了java.lang.Comparable和java.util.Comparator,如果你想有深入的了解的话,可以参考jdk1.8 API,里面讲的还是很详细的
最后还是把这两个接口里面的主要方法给大家说一下吧
Comparable:compareTo(T t)
Comparator:compareTo(T t1,T,t2)///equals(Object obj)
使用策略模式不一定是要写比较,而是各种各样的策略进行选择
下面的为扩展:
如果你对Lambda表达式有所了解话,测试类可以改为这样
Main.java
package 策略模式;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
Cat[] a={new Cat(3,3),new Cat(4,4),new Cat(9,9),new Cat(1,1)};
Sorter2<Cat> sorter2=new Sorter2<>();
sorter2.sort(a,(o1,o2)->{
if(o1.weight<o2.weight) return -1;
else if (o1.weight>o2.weight) return 1;
return 0;
});
System.out.println(Arrays.toString(a));
}
}
在你指定了想要比较的对象时,可以用用Lambda表达式来代替比较器
因为Comparator.java接口中只有一个方法