zoukankan      html  css  js  c++  java
  • 策略模式Strategy

      在jdk中,封装了Comparable和Comparator接口,但是这两个接口的作用是干嘛的呢?在这里做下简单的介绍。

      在平时的练习中,想必大家都做过排序的操作吧?但对排序的操作如果写死在程序里面的话,那在对不同类型的数据进行排序,如int、float甚至是自己新建的类的话,是不是就要重载好几个排序的方法呢?这样的方式肯定是不合适的。

      那么这个时候我们就可以新建一个Comparable接口,在这个接口中建立一个comparaTo()方法,表示是进行比较的操作,具体比较的方法,在具体的实现该接口的类中操作,如下

     

    public int comparaTo(Object o);

      

      假如现在想对猫Cat这个类进行排序,那么在Cat这个类中就需要实现Comparable接口,并覆写好方法,当然在这个类中会存在一些属性,如name,age,用于排序。

    范例:Cat中覆写comparaTo()方法

     

    @Override

             public int comparaTo(Object o) {

                       if(o instanceof Cat){

                           Cat c=(Cat)o;   //强制转换

                           if(this.age>c.getAge()) return 1;

                           else if(this.age>c.getAge()) return -1;

                          else return 0;

                       }

                       return -100;

             }

     

      在上面的操作中,一般是先要判断o是否为Cat的对象,否则的话应该抛出异常,表示不是同一个对象,不能进行比较。在这里就直接返回-100,进行标记即可。

      如果要比较的对象是Cat对象的话,那么就把o强制转换成Cat对象,然后根据age进行排序,返回1表示当前Cat的对象(this)的age大于传递进来的对象(o)的age。返回-1表示小于,0表示等于。

      那么在具体的在具体的排序类中就可以用一下代码进行比较了

     

    public static void sort(Object[] c) {

                       for(int i=c.length;i>0;i--){

                                for(int j=0;j<i-1;j++){

                                         if(c[j].comparaTo(c[j+1])>0){ //大于,表示要进行交换 

                                                   swap(c,j,j+1);   //进行交换

                                         }

                                }

                       }

             }

      

      这样就可以进行根据Cat的age进行排序了。

      只是大家应该会发现,这个时候Cat类中的comparaTo()方法是写死的,也就是说只能通过Cat的age属性进行排序,那这样拓展性是很差的,如果要是想用其他属性进行排序的话,是否就意味着要去修改comparaTo()方法呢?这样的操作肯定是不推崇的。

      所以这个时候就可以用到Comparator接口了,在接口中建立一个compara()方法

     

    /**

              * 根据对象的属性进行比较,即生成自己的比较器

              * @param o1

              * @param o2

              * @return

              */

             int compare(Object o1,Object o2);         //在interface中默认的修饰符是public

     

      然后新建一个java类,表示排序的策略,比较创建一个CatAgeCompartor类,表示一个策略器,这个策略器是根据Cat的age进行排序的。

    范例:编写CatAgeCompartor类,覆写compara()方法

     

    @Override

             /**

              * 定义自己的比较器,这里用age

              */

             public int compare(Object o1, Object o2) {

                       Cat c1 = (Cat) o1;   // 强制转换

                       Cat c2 = (Cat) o2;     // 强制转换

                       if(c1.getAge()>c2.getAge())return 1;

                       else if(c1.getAge()<c2.getAge()) return -1;

                       else return 0;

             }

     

      在这里的方法表示是根据age进行排序,就不加以说明了。所以这个时候在Cat中的comparaTo()方法就可以灵活的使用了。进行如下操作:

     

    private Comparator comparator=new CatAgeComparator();        //实例化猫自己的比较器

    @Override

    public int comparaTo(Object o) {

             return comparable.compare(this, o);

    }

     

      这样就可以根据Cat的age进行排序了,这样拓展性就强多了。比如现在Cat这个类又有一个weight属性,然后你想根据weight进行排序的时候,只需要创建一个策略器CatWeightCompartor,记得实现Comparator接口,覆写对应的方法即可。这样是不是就方便多了呢?

      其实jdk已经把这些操作全部都实现好了,所以我们只需要进行使用就行了,当想进行排序的时候,调用jdk自带的sort()方法就可以了,不过如果是对自己新建的类进行排序的话,那么记得实现类要实现Comparable接口,策略器要实现Comparator接口,而且jdk封装的这些方法中都使用了泛型,那这个时候在实现接口的实现把要进行比较的类传递进行,后续的操作就不再需要进行强制转换了。

    代码:

    Comparable接口

    public interface Comparable {

             /**

              * 表示跟一个对象进行比较,返回int类型的值,

              * @param o  传递的object对象

              * @return

              */

             public int comparaTo(Object o);

    }

    Comparator接口

    public interface Comparator {

             /**

              * 根据对象的属性进行比较,即生成自己的比较器

              */

             int compare(Object o1,Object o2);        //在interface中默认的修饰符是public

    }

    CatAgeComparator

    public class CatAgeComparator implements Comparator {

             @Override

             /**

              * 定义自己的比较器,这里用age

              */

             public int compare(Object o1, Object o2) {

                       Cat c1 = (Cat) o1;   // 强制转换

                       Cat c2 = (Cat) o2;     // 强制转换

                       if(c1.getAge()>c2.getAge())return 1;

                       else if(c1.getAge()<c2.getAge()) return -1;

                       else return 0;

             }

    }

    Cat类关键代码

    public class Cat implements Comparable{

             private String name;

             private int age;

             private Comparator comparator=new CatAgeComparable();        //实例化猫自己的比较器

       //省略getter、setter、toString

             public Cat(String name, int age) {

                       super();

                       this.name = name;

                       this.age = age;

             }

             @Override

             /**

              * 进行猫自己的比较

              */

             public int comparaTo(Object o) {

                       return comparator.compare(this, o);

             }

    }

    Sort类关键代码

    public static void sort(Comparable[] c) {

                       for(int i=c.length;i>0;i--){

                                for(int j=0;j<i-1;j++){

                                         if(c[j].comparaTo(c[j+1])>0){ //大于,表示要进行交换 

                                                   swap(c,j,j+1);   //进行交换

                                         }

                                }

                       }

             }

    测试类Test

    Cat c[]={new Cat("小花12",4),new Cat("小白",1),new Cat("小黑仔",3)};

                       ObjectSort.sort(c);   //排序

                       ObjectSort.print(c);  //打印

     

  • 相关阅读:
    0316-复利计算更新
    实验一 了解和掌握操作系统
    复利计划1.0
    0916 词法分析(2)
    0916词法分析
    0909 编译原理 第1次上机
    单元测试代码
    单元测试
    实验一:命令解释程序
    《构建之法》现代软件工程第1、2、3章读后感
  • 原文地址:https://www.cnblogs.com/littleQin/p/3622424.html
Copyright © 2011-2022 走看看