博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java设计模式——Comparable接口&&Comparator(CC系)策略模式的应用[续]
阅读量:4030 次
发布时间:2019-05-24

本文共 6112 字,大约阅读时间需要 20 分钟。

转自:http://blog.csdn.net/acmman/article/details/46634565

接着上一篇总结继续探讨。

之前我们的DataSorter的Sort方法虽然可以对任何实现了Comparable接口的对象进行排序,不过,麻烦事在于,这些对象实现的comparaTo方法只有一种实现,只能写一种,不能写太多,而且将来我想任意的扩展怎么计算两个对象谁大谁小的规范,这个时候这个类该如何设计呢?


现在我们对其进行实现。大家想想看,我们想对两个对象比较大小的方式进行拓展,这个方式就不能定义为具体的,要定义为抽象的,所以我们定义这样一个接口:

比较器Comparator.java:

[java]   
  1. package cn.edu.hpu.Strategy;  
  2.   
  3. //interface类里面的方法默认都是public  
  4. public interface Comparator {  
  5.     /*实现这个接口的对象使用这个方法进行比较时, 
  6.     *返回1是比那个对象大,返回0是相等,返回-1是比那个对象小*/  
  7.     int compare(Object o1,Object o2);  
  8. }  

我们之前对狗进行的是利用高度进行排序,现在我们用其重量来比较大小。

我们重新创建一个类,叫做"狗的根据重量的比较器",它去实现Comparator接口

[java]   
  1. package cn.edu.hpu.Strategy;  
  2.   
  3. public class DogWeightComparator implements Comparator{  
  4.   
  5.   
  6.     @Override  
  7.     public int compare(Object o1, Object o2) {  
  8.         Dog d1=(Dog)o1;  
  9.         Dog d2=(Dog)o2;  
  10.         if(d1.getWeight()>d2.getWeight()) return 1;  
  11.         else if(d1.getWeight()<d2.getWeight()) return -1;  
  12.         return 0;  
  13.     }  
  14.   
  15.   
  16. }  

对于狗来说,我们之前实现Comparable接口了,此时比较逻辑不要在comparaTo()方法中写死,我们在comparaTo()中new出一个DogWeightComparator比较器,来比较当前的对象和传进来的对象的大小。

[java]   
  1. package cn.edu.hpu.Strategy;  
  2.   
  3. public class Dog implements Comparable{  
  4.     //狗的身高  
  5.     private int height;  
  6.     //狗的体重  
  7.     private int weight;  
  8.       
  9.     public Dog(int height, int weight) {  
  10.         super();  
  11.         this.height = height;  
  12.         this.weight = weight;  
  13.     }  
  14.     public int getHeight() {  
  15.         return height;  
  16.     }  
  17.     public void setHeight(int height) {  
  18.         this.height = height;  
  19.     }  
  20.     public int getWeight() {  
  21.         return weight;  
  22.     }  
  23.     public void setWeight(int weight) {  
  24.         this.weight = weight;  
  25.     }  
  26.     @Override  
  27.     public int compareTo(Object o) {  
  28.         return new DogWeightComparator().compare(this, o);  
  29.     }  
  30.     @Override  
  31.     public String toString() {  
  32.         return this.getHeight()+"|"+this.getWeight();  
  33.     }  
  34.       
  35.       
  36. }  

这个时候你就会发现好处:假如我对重量比较不满意了,我可以换成new别的来实现别的比较方法。

我们最好设置一个成员变量,是比较器Comparator类型的,设好它的get和set方法,具体向里面放什么样的比较器,我们在comparaTo()方法中就引用什么样的比较器来比较大小。

[java]   
  1. package cn.edu.hpu.Strategy;  
  2.   
  3.   
  4. public class Dog implements Comparable{  
  5.     //狗的身高  
  6.     private int height;  
  7.     //狗的体重  
  8.     private int weight;  
  9.     //比较器(默认指定DogWeightComparator)  
  10.     private Comparator comparator=new DogWeightComparator();  
  11.       
  12.     public Dog(int height, int weight) {  
  13.         super();  
  14.         this.height = height;  
  15.         this.weight = weight;  
  16.     }  
  17.     public Comparator getComparator() {  
  18.         return comparator;  
  19.     }  
  20.   
  21.   
  22.     public void setComparator(Comparator comparator) {  
  23.         this.comparator = comparator;  
  24.     }  
  25.     public int getHeight() {  
  26.         return height;  
  27.     }  
  28.     public void setHeight(int height) {  
  29.         this.height = height;  
  30.     }  
  31.     public int getWeight() {  
  32.         return weight;  
  33.     }  
  34.     public void setWeight(int weight) {  
  35.         this.weight = weight;  
  36.     }  
  37.     @Override  
  38.     public int compareTo(Object o) {  
  39.         return comparator.compare(this, o);  
  40.     }  
  41.     @Override  
  42.     public String toString() {  
  43.         return this.getHeight()+"|"+this.getWeight();  
  44.     }  
  45.       
  46.       
  47. }  
测试:

[java]   
  1. package cn.edu.hpu.Strategy;  
  2.   
  3.   
  4. public class Test {  
  5.     public static void main(String[] args) {;   
  6.         Dog[] dogs={
    new Dog(3,8),new Dog(5,4),new Dog(1,2)};  
  7.         DataSorter.sort(dogs);   
  8.         DataSorter.p(dogs);  
  9.     }  
  10. }  

结果:

1|2 5|4 3|8 

我们发现使用狗的重量来排序了。


当我们使用新创建的Comparator接口的时候,你会发现世界又美好了一些,因为我写完一个Dog类之后我还可以跟着设置他们两个对象之间的比较方式,这样我们类的扩展能力就更强了。


大家仔细想想Comparable、Comparator接口与DataSorter和比较类Dog、Cat之间的关系,就会总结出Comparator接口出现的好处。


下一篇总结收尾。

转载请注明出处:

转自:http://blog.csdn.net/acmman/article/details/46634607

接着上边总结继续探讨。

我们之前用自己的方式来实现了JDK的Comparable和Comparator接口,我们下面来看看实际当中JDK给我们的Comparable和Comparator接口。


我们对之前的Dog和Dog的比较类DogWeightComparator的实现进行修改:

Dog.java:

[java]   
  1. package cn.edu.hpu.Strategy;  
  2.   
  3. public class Dog implements java.lang.Comparable<Dog>{  
  4.     //狗的身高  
  5.     private int height;  
  6.     //狗的体重  
  7.     private int weight;  
  8.     //比较器(默认指定DogWeightComparator)  
  9.     private java.util.Comparator<Dog> comparator=new DogWeightComparator();  
  10.       
  11.     public Dog(int height, int weight) {  
  12.         super();  
  13.         this.height = height;  
  14.         this.weight = weight;  
  15.     }  
  16.       
  17.     public java.util.Comparator getComparator() {  
  18.         return comparator;  
  19.     }  
  20.   
  21.   
  22.     public void setComparator(java.util.Comparator comparator) {  
  23.         this.comparator = comparator;  
  24.     }  
  25.   
  26.   
  27.     public int getHeight() {  
  28.         return height;  
  29.     }  
  30.     public void setHeight(int height) {  
  31.         this.height = height;  
  32.     }  
  33.     public int getWeight() {  
  34.         return weight;  
  35.     }  
  36.     public void setWeight(int weight) {  
  37.         this.weight = weight;  
  38.     }  
  39.     @Override  
  40.     public int compareTo(Dog o) {  
  41.         return comparator.compare(this, o);  
  42.     }  
  43.     @Override  
  44.     public String toString() {  
  45.         return this.getHeight()+"|"+this.getWeight();  
  46.     }  
  47.       
  48.       
  49. }  

DogWeightComparator.java:

[java]   
  1. package cn.edu.hpu.Strategy;  
  2.   
  3.   
  4. public class DogWeightComparator implements java.util.Comparator<Dog>{  
  5.   
  6.   
  7.     @Override  
  8.     public int compare(Dog o1, Dog o2) {  
  9.         Dog d1=(Dog)o1;  
  10.         Dog d2=(Dog)o2;  
  11.         if(d1.getWeight()>d2.getWeight()) return 1;  
  12.         else if(d1.getWeight()<d2.getWeight()) return -1;  
  13.         return 0;  
  14.     }  
  15.   
  16.   
  17. }  

DataSorter中的类型也要改成java.lang.Comparable

DataSorter.java:

[java]   
  1. package cn.edu.hpu.Strategy;  
  2.   
  3.   
  4. public class DataSorter {  
  5.   
  6.   
  7.     public static void sort(Object[] a) {  
  8.         for (int i = a.length; i >0; i--) {  
  9.             for (int j = 0; j < i-1; j++) {  
  10.                 java.lang.Comparable o1=(java.lang.Comparable)a[j];  
  11.                 java.lang.Comparable o2=(java.lang.Comparable)a[j+1];  
  12.                 if(o1.compareTo(o2)==1){  
  13.                     swap(a,j,j+1);  
  14.                 }  
  15.             }  
  16.         }  
  17.           
  18.     }  
  19.       
  20.     private static void swap(Object[] a, int x, int y) {  
  21.         Object temp=a[x];  
  22.         a[x]=a[y];  
  23.         a[y]=temp;  
  24.           
  25.     }     
  26.       
  27.     public static void p(Object[] a) {  
  28.         for (int i = 0; i < a.length; i++) {  
  29.             System.out.print(a[i]+" ");  
  30.         }  
  31.         System.out.println();  
  32.     }  
  33.   
  34.   
  35. }  

测试(按重量排序):

[java]   
  1. package cn.edu.hpu.Strategy;  
  2.   
  3.   
  4. public class Test {  
  5.     public static void main(String[] args) {  
  6.         //int[] a={9,5,3,7,1};   
  7.   
  8.   
  9.         Dog[] dogs={
    new Dog(3,8),new Dog(5,4),new Dog(1,2)};  
  10.         DataSorter.sort(dogs);   
  11.         DataSorter.p(dogs);  
  12.         /* 
  13.         Cat[] cats={new Cat(21),new Cat(15),new Cat(9)}; 
  14.         DataSorter.sort(cats);  
  15.         DataSorter.p(cats);*/  
  16.     }  
  17. }  

测试结果:

1|2 5|4 3|8 


我们探讨了JDK的Comparable和Comparator接口的使用,是不是和我们自己写的那个使用方法和效果完全一样(唯一区别就是JDK的接口使用了泛型,泛型的好处就是不用再强制转换了)?说明我们已经成功模拟出了JDK的Comparable和Comparator接口。


再来看,刚刚我们自己写了sort方法,其实我们也不用写这个方法,可以使用java.Util.Arrays.sort(a);进行排序,前提是只要实现了java.lang.Comparable接口即可。

测试:

[java]   
  1. package cn.edu.hpu.Strategy;  
  2.   
  3.   
  4. public class Test {  
  5.     public static void main(String[] args) {  
  6.         //int[] a={9,5,3,7,1};   
  7.   
  8.   
  9.         Dog[] dogs={
    new Dog(3,8),new Dog(5,4),new Dog(1,2)};  
  10.         java.util.Arrays.sort(dogs);   
  11.         DataSorter.p(dogs);  
  12.     }  
  13. }  
测试结果:

1|2 5|4 3|8 

是不是也可以?当然可以


为什么说数据结构和算法在日常工作中不重要了,是因为这些东西在Java中已经给大家封装的很好了,大家只需要懂得原理,巧妙的去使用他们即可。


写了这些我们发现JDK中都有,是不是白写了?不是,写完Comparable和Comparator接口,我们就学习了策略模式,深入学习了Comparable和Comparator接口的设计模式。


那么什么是策略模式?在本例中就是:当进行比较大小的时候,定义一个策略的比较器,然后由具体的比较策略来决定到底谁大谁小。


作业:

封装一下商场的打折策略

现在商场都有许多打折活动,我们的打折策略不能写死,所以我们最好把打折策略定义成一个可以拓展的策略。


作业在以后总结总解答

转载请注明出处:

你可能感兴趣的文章
Android计算器实现源码分析
查看>>
Android系统构架
查看>>
Android 跨应用程序访问窗口知识点总结
查看>>
各种排序算法的分析及java实现
查看>>
SSH框架总结(框架分析+环境搭建+实例源码下载)
查看>>
js弹窗插件
查看>>
自定义 select 下拉框 多选插件
查看>>
js判断数组内是否有重复值
查看>>
js获取url链接携带的参数值
查看>>
gdb 调试core dump
查看>>
gdb debug tips
查看>>
arm linux 生成火焰图
查看>>
jtag dump内存数据
查看>>
linux和windows内存布局验证
查看>>
linux config
查看>>
linux insmod error -1 required key invalid
查看>>
linux kconfig配置
查看>>
linux不同模块completion通信
查看>>
linux printf获得时间戳
查看>>
C语言位扩展
查看>>