欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

从java的Comparable和Comparator接口学习策略模式

程序员文章站 2022-05-22 13:07:56
...
我们知道java.util.Arrays中有一个sort()方法可以对所有数组进行排序比如:
import java.util.Arrays;

public class TestSort {
    public static void main(String[] args) {
        int[] arr = {1,9,5,10,8,2,7,4,3};
        Arrays.sort(arr);
        for(int i:arr){
            System.out.print(i+"  ");
        }
    }
}

输出:1  2  3  4  5  7  8  9  10 

import java.util.Arrays;

public class TestSort {
    public static void main(String[] args) {
        String[] arr = {"ni","hao","hello","test"};
        Arrays.sort(arr);
        for(String  i:arr){
            System.out.print(i+"  ");
        }
    }
}
   输出:hao  hello  ni  test 

那么究竟这个方法怎么对数组进行排序的呢,而且对于String数组有着怎样的排序策略呢?首先我们来看方法介绍:

从java的Comparable和Comparator接口学习策略模式

文档中说明了数组中的所有元素都必须实现 Comparable 接口,我们看一下Integer和String类的源码:

从java的Comparable和Comparator接口学习策略模式

从java的Comparable和Comparator接口学习策略模式

从java的Comparable和Comparator接口学习策略模式


从java的Comparable和Comparator接口学习策略模式

从java的Comparable和Comparator接口学习策略模式

可以看到他们都实现了Comparable接口,重写了compareTo方法,具体的比较方式是自己实现的,比如int值是按照数字的大小比较,String是先按照首字母在字母表中的顺序比较,如果顺序相同再比较他们的长度。这也是不同的类可以实现自己独特的比较方式,比如你也可以自己写一个MyString按照其他的方式进行比较。这就是策略模式,就拿比较而言定义了Comparable接口,不同的实现类实现不同的算法,也就是不同的策略。那我们自己定义的类不同的对象也就可以进行比较了,下面我们写自己的一个Cat类,并用sort进行排序:

package cat;

import java.util.Arrays;
import java.util.Comparator;

public class Test {
    public static void main(String[] args) {
        Cat[] cats = {new Cat(1,1),new Cat(5,5),new Cat(3,3)};
        Arrays.sort(cats);
        for(Cat c:cats){
            System.out.println(c);
        }
    }
}

class Cat implements Comparable<Cat>{
    private int height;
    private int weight;

    public Cat(int height, int weight) {
        this.height = height;
        this.weight = weight;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public int getWeight (){
        return this.weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }

    @Override
    public String toString() {
        return "Cat{" +
                "height=" + height +
                ", weight=" + weight  +
                '}';
    }

    @Override
    //我们按照猫的重量来比较大小
    public int compareTo(Cat o) {
        if(this.getWeight()>o.getWeight()){
            return 1;
        }else if(this.getWeight()<o.getWeight()){
            return -1;
        }else{
            return 0;
        }
    }
}



结果:Cat{height=1, weight=1}
  Cat{height=3, weight=3}
                  Cat{height=5, weight=5}

如果我们不适用策略模式,那么每次新建类想要进行排序的时候都要自己写排序方法,写比较方法。现在还是有问题,比如现在比较两只猫的大小是根据体重比较,如果我现在想根据猫的身高进行比较大小怎么办,就需要重新写比较方法。那如果再写一个类Dog相比较他们的大小就需要把比较策略重写一遍。这时候就轮到Comparator比较器发挥作用了

import java.io.File;
import java.util.Arrays;
import java.util.Comparator;

public class Test {
    public static void main(String[] args) {
        Cat[] cats = {new Cat(1,1),new Cat(5,5),new Cat(3,3)};
        Arrays.sort(cats);
        for(Cat c:cats){
            System.out.println(c);
        }
    }
}

class Cat implements Comparable<Cat>{
    private int height;
    private int weight;
    //这里改变new的比较器就可以实现不同的比较
    private Comparator<Cat> catComparator = new CatHeightComparator();

    public Cat(int height, int weight) {
        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(Cat o) {
        return catComparator.compare(this,o);
    }

    @Override
    public String toString() {
        return "Cat{" +
                "height=" + height +
                ", weight=" + weight  +
                '}';
    }
}
//根据身高比较大小的比较器
class CatHeightComparator implements Comparator<Cat>{

    @Override
    public int compare(Cat o1, Cat o2) {
        if(o1.getHeight()>o2.getHeight()){
            return 1;
        }else if(o1.getHeight()<o2.getHeight()){
            return -1;
        }else{
            return 0;
        }
    }
}

//根据体重比较大小的比较器
class CatWeightComparator implements Comparator<Cat>{

    @Override
    public int compare(Cat o1, Cat o2) {
        if(o1.getWeight()>o2.getWeight()){
            return 1;
        }else if(o1.getWeight()<o2.getWeight()){
            return -1;
        }else{
            return 0;
        }
    }
}