Skip to content

Latest commit

 

History

History
398 lines (299 loc) · 9.34 KB

14. Comparable.md

File metadata and controls

398 lines (299 loc) · 9.34 KB

14. Comparable

面向接口编程

Comparable接口中只有一个方法

public int compareTo(Object obj)

返回0:this==obj

返回正数:this>obj

返回负数:this<obj

实现Comparable接口的类通过实现compareTo方法确定该类对象的排序方式;

独立于实体类,便于应对各种排序规则;

package com.alexanderli95.innerType;

import java.util.Date;

/**
* 内置引用数据类型的比较(常用的)
*/
public class Demo01 {
   public static void main(String[] args) {
       /**
        *根据基本数据类型比较
        *return (x < y) ? -1 : ((x == y) ? 0 : 1);
        */
       Integer i;

       /**
        * 根据Unicode编码比较
        * return x - y;
        */
       Character c;

       /**
        * public int compareTo(String anotherString) {
        *         int len1 = value.length;
        *         int len2 = anotherString.value.length;
        *         int lim = Math.min(len1, len2);
        *         char v1[] = value;
        *         char v2[] = anotherString.value;
        *
        *         int k = 0;
        *         while (k < lim) {
        *             char c1 = v1[k];
        *             char c2 = v2[k];
        *             if (c1 != c2) {
        *                 return c1 - c2;
        *             }
        *             k++;
        *         }
        *         return len1 - len2;
        *     }
        *
        * 如果前一个是另一个起始部分的字串,返回长度之差;否则返回第一个不相等的字符的Unicode编码差
        */
       String str;

       //根据日期的长整形数比较
       Date date;

   }
}

工具类Utils的实现:

package com.alexanderli95.innerType;

import java.util.List;

/**
 * 自己实现一个工具类(排序)
 */
public class Utils {

    //数组降序排序
    public static void sort(Object[] data){
        boolean sorted=true;

        int times=data.length;
        //冒泡排序
        for(int j=0;j<data.length;j++) {
            sorted=true;
            for (int i = 0; i < times-1; i++) {
                if (((Comparable)data[i]).compareTo(data[i + 1])>0) {
                    Object temp = data[i];
                    data[i] = data[i + 1];
                    data[i + 1] = temp;
                    sorted=false;
                }
            }

            if(sorted){
                break;
            }

            times--;
        }
    }

    //使用泛型方法
    public static <T extends Comparable>void sort(T[] data){
        boolean sorted=true;

        int times=data.length;
        //冒泡排序
        for(int j=0;j<data.length;j++) {
            sorted=true;
            for (int i = 0; i < times-1; i++) {
                if (((Comparable)data[i]).compareTo(data[i + 1])>0) {
                    T temp = data[i];
                    data[i] = data[i + 1];
                    data[i + 1] = temp;
                    sorted=false;
                }
            }

            if(sorted){
                break;
            }

            times--;
        }
    }

    //容器排序
    public static <T extends Comparable> void sort(List<T> array){
        Object[] data=array.toArray();
        sort(data);

        for(int i=0;i<data.length;i++){
            array.set(i,(T)data[i]);
        }
    }
}

JDK 自带的Collections类

package com.alexanderli95.innerType;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Collection
 */
public class Demo05 {
    public static void main(String[] args) {
        List<String> list=new ArrayList<String>();
        String[] strings={"a","asd","as","asdfg","wwww"};

        for(int i=0;i<strings.length;i++){
            list.add(strings[i]);
        }

        //调用了重写的compare方法
        Collections.sort(list,new StringComp());  //public static <T> void sort(List<T> list, Comparator<? super T> c)
        System.out.println(list);

        System.out.println("================================");

        //调用默认compare方法
        List<String> list2=new ArrayList<String>();
        String[] strings2={"a","asd","as","asdfg","wwww"};

        for(int i=0;i<strings2.length;i++){
            list2.add(strings2[i]);
        }
        Collections.sort(list2);
        System.out.println(list2);
    }

}

实现compareTo()方法,实现新闻类的排序:

1.NewsItem.java

package com.alexanderli95.innerType;

import java.text.SimpleDateFormat;
import java.util.Date;

public class NewsItem implements java.lang.Comparable<NewsItem> {

    private String title;      //标题
    private int hint;          //点击量
    private Date publishTime;  //发布时间

    public NewsItem(String title, int hint, Date publishTime) {
        this.title = title;
        this.hint = hint;
        this.publishTime = publishTime;
    }

    public NewsItem() {
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public int getHint() {
        return hint;
    }

    public void setHint(int hint) {
        this.hint = hint;
    }

    public Date getPublishTime() {
        return publishTime;
    }

    public void setPublishTime(Date publishTime) {
        this.publishTime = publishTime;
    }

    //时间降序+点击量降序+标题降序
    @Override
    public int compareTo(NewsItem o) {

        int result=0;
        result=-this.publishTime.compareTo(o.publishTime);

        if(0==result){  //时间相同
            //比较点击量
            result=-(this.hint-o.hint);
            if(0==result){  //点击量相同
                //比较标题
                result=-this.title.compareTo(o.title);
            }
        }

        return result;
    }

    @Override
    public String toString() {

        StringBuilder sb=new StringBuilder();
        sb.append("标题:").append(this.title);
        sb.append(" 点击量:").append(this.hint);
        sb.append(" 发布日期:").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.publishTime));
        sb.append("\n");

        return sb.toString();

    }
}

2.NewsItemApp.java

package com.alexanderli95.innerType;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

public class NewsItemApp {
    public static void main(String[] args) {
        List<NewsItem> news=new ArrayList<NewsItem>();
        news.add(new NewsItem("行业改革",100,new Date(System.currentTimeMillis())));
        news.add(new NewsItem("社保",90,new Date(System.currentTimeMillis()-60*60*1000)));
        news.add(new NewsItem("医疗",900,new Date(System.currentTimeMillis())));

        Collections.sort(news);   //sort会自动调用compareTo()方法

        System.out.println(news);
    }
}

商品类的排序:

==思想==:Goods类只作为一个JavaBean(解耦:与实体类分离,保证实体类的独立性和完整性),额外增加GoodsPriceComp类用于按照价格进行排序,优势在于:如果需要通过其他属性进行排序,不需要改变原来的代码,只需要增加新的类即可(方便:可以方便的应对多变的排序规则);

1.Goods.java

package com.alexanderli95.innerType;

public class Goods {
    private String name;
    private int fav;
    private double price;

    @Override
    public String toString() {
        return "商品名:"+this.name+" 收藏量:"+this.fav+" 价格:"+this.price+"\n";
    }

    public Goods(String name, int fav, double price) {
        this.name = name;
        this.fav = fav;
        this.price = price;
    }

    public Goods() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getFav() {
        return fav;
    }

    public void setFav(int fav) {
        this.fav = fav;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}

2.GoodsPriceComp.java

package com.alexanderli95.innerType;

public class GoodsPriceComp implements java.util.Comparator<Goods>{

    //比较价格(降序)
    @Override
    public int compare(Goods o1, Goods o2) {
        return -(o1.getPrice()-o2.getPrice()>0?1:(o1.getPrice()==o2.getPrice()?0:-1));
    }
}

3.GoodsApp.java

package com.alexanderli95.innerType;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class GoodsApp {
    public static void main(String[] args) {
        List<Goods> goods=new ArrayList<Goods>();
        goods.add(new Goods("iphone 8",100,8000));
        goods.add(new Goods("Samsung x",60,6000));
        goods.add(new Goods("Mi 9",500,7999));

        Collections.sort(goods,new GoodsPriceComp());   //sort会自动调用GoodsPriceComp中的compare()方法

        System.out.println(goods);
    }
}