JDK设计模式之——策略模式(Comparable和Comparator接口)

策略模式:其实就是java的多态。。。父类引用指向子类对象。

使用策略模式,改善排序算法上文中需要排序的是一个数组 让他可以对任何类型的数组进行排序

1.利用 接口 Comparable<T>

  只要数组里面的这些个对象,都去实现 comparable接口, 然后实现compareTo()方法。

int compareTo(T o) 
          比较此对象与指定对象的顺序。

 举例 我们想比较在比较一个对象Cat 只需要让Cat对象去实现Comparable接口

public class Cat implements Comparable<Cat>{
    private int height;
    
    public int getHeight() {
        return height;
    }
    public void setHeight(int height) {
        this.height = height;
    }
    
    /**
     * 下面是自己定义的比较策略
     * 如果本对象比穿过来的对象的高度高 就返回1 
     * 如果没有参数传过来的对象高 就返回-1
     * 相等返回0
     */
    @Override
    public int compareTo(Cat cat) {
        if(this.getHeight()>cat.getHeight()){
            return 1;
        }else if(this.getHeight()<cat.getHeight()){
            return -1;                    
        }else{
            return 0;
        }
    }
}

然后修改一下 我们的比较接口

/**
 * 然后修改我们的排序算法,
 * 这样我们的排序算法 就可以比较任何类而不用做任何改动
 * 前提是需要比较的类必须实现comparable接口()
 */
public class SelectionSort {
    //TODO java不允许创建泛型数组 不知道为何,所以代码有些黄色警告,不过并不影响本文所说的策略模式
    public static void sort(Object[] arr){
        int len = arr.length;
        for(int i=0;i<len;i++){
            //寻找i到len里面的最小值  并把最小值的索引存在minIndex当中  即 寻找最小值的索引
            int minIndex = i;
            for( int j = i + 1 ; j < len ; j ++ ){//i + 1
                Comparable o1 =(Comparable)arr[j];
                Comparable o2 =(Comparable)arr[minIndex];
                if( o1.compareTo(o2)==-1 ){  //等于-1 就说明arr[j]<arr[minIndex]
                     minIndex = j;  //不断的寻找 最小值的索引
                }
            }
            swap( arr , i , minIndex); //找到最小值后和当前没有排序的第一个位置进行交换位置
        }
    }
    
    private static void swap(Object[] arr, int i, int j) {
        Object t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }
}

这种利用Comparable的优点就是 我们的排序算法只需要写一次,对所有类都可以支持。

(JDK String int Long float 都已经内部帮我们实现了comparable接口 我们可以直接用 comparableTo()进行比较这些基本类型)

jdk对策略模式的补充

以上代码 在Cat中 我们把比较策略(这可能就是策略模式名字的来源吧) 写死了,现在我们不光想要把我们的算法策略抽出来,我们也想把比较策略抽出来。

现在介绍另一个接口

接口 Comparator<T>

int compare(T o1, T o2) 
          比较用来排序的两个参数。

 可以发现 此接口也存在一个comparableTo() 方法,但是与之前不同的是,此方法要接收两个对象

public class Cat implements Comparable<Cat>{
    
    //可以写成多态
    Comparator<Cat> comparator = new CatHeightComparator<Cat>();
    
    private int height;
    
    public int getHeight() {
        return height;
    }
    public void setHeight(int height) {
        this.height = height;
    }
    
    //把具体怎么样比较的代码  写在一个比较器中,而不是写在类本身的代码里(同一个类在不同的业务中 可能有不同的比较方法)
    @Override
    public int compareTo(Cat cat) {
        return  comparator.compare(this, cat);
    }
    
    Cat(int height){
        this.height=height;
    }
    
    //比较器
    public class CatHeightComparator<T> implements Comparator<T> {
        @Override
        public int compare(T o1, T o2) {
            Cat c1 = (Cat) o1;
            Cat c2 = (Cat) o2;
            if(c1.getHeight()>c2.getHeight()){
                return 1;
            }
            if(c1.getHeight()<c2.getHeight()){
                return -1;
            }
            return 0;
        }
    }
    
    //main方法测试
    public static void main(String[] args) {
       Cat[] a ={new Cat(2),new Cat(3) ,new Cat(1)};
       SelectionSort.sort(a);
       for (Cat cat : a) {
           System.out.println(cat.getHeight());
       }
    }
}

策略模式 看起来就是多态和封装。

不仅是策略模式 java所有的设计模式 都是多态和封装的应用

补充:JDK中

java.util.Arrays 有一个sort()方法
static
<T> void
sort(T[] a, Comparator<? super T> c) 
          根据指定比较器产生的顺序对指定对象数组进行排序。
java.util.Collections 也有一个sore()方法
static
<T> void
sort(List<T> list, Comparator<? super T> c) 
          根据指定比较器产生的顺序对指定列表进行排序。

 o1 - 要比较的第一个对象。o2 - 要比较的第二个对象。

  根据第一个参数小于、等于或大于第二个参数分别返回负整数、零或正整数。


 

原文地址:https://www.cnblogs.com/ssskkk/p/8784542.html