Java容器的两种排序java.lang.Comparable + compareTo()和java.util.Comparator + compare()

java.util.Comparator和compare方法

这个主要是提供额外的业务排序类,然后对某个实体类进行排序,总的来说就是实现Comparator接口,重写compare方法,看程序样例:


import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
 * 提供额外的业务排序类
 * 按价格排序    
 * Goods类的辅助类
 * 实现Comparator接口,重写compare方法
 * o1 > o2的话升序  o1 < o2就降序
 * @author 郑鑫
 *
 */

class GoodsPriceCompare implements java.util.Comparator{
    @Override
    public int compare(Goods o1, Goods o2) { //降序排列(在前面加一个负号)
        return -(o1.getPrice() - o2.getPrice() > 0 ? 1 :(o1.getPrice() == o2.getPrice() ? 0 : -1)); 
    }   
}

/**
 * 没有实现接口的实体类
 * @author 郑鑫
 */

public class Goods {
    private String name;// 商品名称
    private double price;
    private int fav; // 收藏量

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

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

    //setter,getter方法
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    public int getFav() {
        return fav;
    }
    public void setFav(int fav) {
        this.fav = fav;
    }

    public static void main(String[] args) {
        Listlist = new ArrayList();
        list.add(new Goods("老fei视频",0,1000));
        list.add(new Goods("老ma视频", 100, 2000));
        list.add(new Goods("老gao视频",50,1000));
        System.out.println("--------------排序前-------------");
        System.out.println(list);
        Collections.sort(list,new GoodsPriceCompare());   //Collections类中的sort()方法
        System.out.println("--------------排序后-------------");//按照价格降序排序
        System.out.println(list);
    }
}

java.lang.Comparable + compareTo()实现排序

也是实现Comparable接口,重写compareTo方法
看一个按照多个标准排序的样例

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
/**
 * 按多个 标准排序的 compareTo方法重写
 * @author 郑鑫
 */

public class NewsItem implements java.lang.Comparable {

    private String title;
    private int hits; //点击量
    private Date putTime;

    public NewsItem() {}

    public NewsItem(String title, int hits, Date putTime) {
        super();
        this.title = title;
        this.hits = hits;
        this.putTime = putTime;
    }

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

    public int getHits() {
        return hits;
    }
    public void setHits(int hits) {
        this.hits = hits;
    }

    public Date getPutTime() {
        return putTime;
    }
    public void setPutTime(Date putTime) {
        this.putTime = putTime;
    }

    //先按时间降序+ 点击量升序 + 标题降序  
    @Override //重写compareTo方法
    public int compareTo(NewsItem o) {
        int result = 0;
        result = -(this.putTime.compareTo(o.putTime));
        if(result == 0) { //相等
            result = this.hits - o.hits;
            if(result == 0) {
                result =  -(this.title.compareTo(o.title));
            }
        }
        return result;
    }

    @Override
    public String toString() { //注意重写的toString方法
        StringBuilder sb = new StringBuilder();
        sb.append("标题 : ").append(this.title).append("  ");
        sb.append(" 时间 : ").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.putTime));
        sb.append(" 点击量: ").append(this.hits).append("\n");
        return sb.toString();
    }

    public static void main(String[] args) {
        Listnews = new ArrayList();
        news.add(new NewsItem("钓鱼带事件: ", 500, new Date()));
        news.add(new NewsItem("南海问题 : ",1500, new Date(System.currentTimeMillis() + 60*60*24*1000)));
        news.add(new NewsItem("马蓉事件 : ",1000, new Date(System.currentTimeMillis() + 60*60*24*1000)));
        System.out.println("--------------排序前-------------");
        System.out.println(news);
        Collections.sort(news); //Collections类中的sort()方法
        //UtilSort.bubbleSort(news); //自定义的
        System.out.println("--------------排序后-------------");//先按时间降序排列,再按点击量升序排列
        System.out.println(news);
    }
}

自己的UtilSort工具类,实现排序

自己写的排序,使用冒泡排序,包括泛型和Object实现:

import java.util.Comparator;
import java.util.List;

public class UtilSort {

    /**
     * 泛型的数组排序 : 使用泛型方法
     */

    public static  > void bubbleSort(T[] arr) {
        for(int j = 0; j < arr.length-1; j++) { //次数
            boolean isChange = false;
            for(int i = 0; i < arr.length - j - 1; i++) {
                if(((Comparable)arr[i]).compareTo(arr[i+1]) > 0) {
                    T temp = arr[i];
                    arr[i] = arr[i+1];
                    arr[i+1] = temp;
                    isChange = true;
                }
            }
            if(!isChange)break; //如果没有改变则可以 结束
        }
    }

    /**
     * Object类型的数组排序
     * @param arr
     */
    public static void bubbleSort(Object arr[]) {
        for(int j = 0; j < arr.length-1; j++) { //次数
            boolean isChange = false;
            for(int i = 0; i < arr.length - j - 1; i++) {
                if(((Comparable)arr[i]).compareTo(arr[i+1]) > 0) {
                    Object temp = arr[i];
                    arr[i] = arr[i+1];
                    arr[i+1] = temp;
                    isChange = true;
                }
            }
            if(!isChange)break; //如果没有改变则可以 结束
        }
    }



    /**
     * 使用泛型对容器排序
     * @param arr
     */
    public static > void bubbleSort(Listlist) {
        //转成数组
        //改变容器中对应的值
        Object[] arr = list.toArray();//由于没有泛型数组,使用Object数组
        bubbleSort(arr);
        for(int i = 0; i < arr.length; i++) {
            list.set(i, (T)arr[i]);
        }
    }


    /**
     * 数组的排序 + Comparator 接口
     */

    public static void bubbleSort(Object arr[],Comparator com) {
        for(int j = 0; j < arr.length-1; j++) { //次数
            boolean isChange = false;
            for(int i = 0; i < arr.length - j - 1; i++) {
                if( com.compare((T)arr[i] , (T)arr[i+1]) > 0) {
                    Object temp = arr[i];
                    arr[i] = arr[i+1];
                    arr[i+1] = temp;
                    isChange = true;
                }
            }
            if(!isChange)break; //如果没有改变则可以 结束
        }
    }

    /**
     * list的排序 + 比较器
     */
    /**
     * 使用泛型对容器排序
     * @param arr
     */
    public static > void bubbleSort(Listlist,Comparatorcom) {
        //转成数组
        //改变容器中对应的值
        Object[] arr = list.toArray();//由于没有泛型数组,使用Object数组
        bubbleSort(arr,com);
        for(int i = 0; i < arr.length; i++) { //list型的排序
            list.set(i, (T)arr[i]);
        }
    }
}

最后再写一个测试类,巩固一下

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

/**
 * 排序规则的业务类
 * 实现Comparator接口,重写compare方法(),按字符串长度比较
 * @author 郑鑫
 */

class StringLengthCompare implements java.util.Comparator {//对String类型的排序
    /**
     * 按长度比较大小
     * 正数: > 
     * 负数: <
     * 0 == 
     */
    @Override
    public int compare(String o1, String o2) { //比较字符串的长度大小
        int len1 = o1.length(); //按长度大小排序
        int len2 = o2.length();
        return len1 - len2; //返回长度之差
    } 
}

/**
 * 内置引用数据类型的比较
 * compareTo测试:
 * int compareTo(Object obj)方法中: 0: this == obj ,正数: this > obj, 负数 : this < obj
 * @author 郑鑫
 */

/**
 * 测试Collections工具类中的sort排序
 * 1.按照Comparable排序
 * public static  void sort (Listlist,Comparable< ? super T>c)  {}
 * 2.public static > void sort(Listlist)
 * void sort(Listlist)
 * @author 郑鑫
 *
 */

public class TestSort {

    public static void main(String[] args) {
        Integer a; //根据基本数据类型大小
        Character ch;  //根据Unicode编码排序
        String str = "abc"; //如果其中一个是另外一个起始开始的字串,返回两个长度之差
        String str2 = "abcd123"; //否则返回第一个不想等的Unicode编码只差
        System.out.println(str.compareTo(str2));

        //测试一  Comparable接口 和冒泡排序
        String[] s = {"a","abcd","ac","b","ab"};
        UtilSort.bubbleSort(s);
        //两种遍历方式
        System.out.println(Arrays.toString(s));
        for(String i:s) {
            System.out.print(i + " ");
        }
        System.out.println();
        System.out.println("------------------");

        //测试二 Comparable接口
        Date[] date = new Date[3];
        date[0] = new Date();
        date[1] = new Date(System.currentTimeMillis() - 1000 * 60 * 60); //现在时间减去一个钟头
        date[2] = new Date(System.currentTimeMillis() + 1000 * 60 * 60);
        UtilSort.bubbleSort(date); //调用工具类的bubbleSort()方法
        System.out.println(Arrays.toString(date)); //按时间排序
        System.out.println("------------------");

        //测试三: 容器测试
        List list = new ArrayList();
        list.add("a");
        list.add("abc");
        list.add("b");
        list.add("ab");
        UtilSort.bubbleSort(list);
        System.out.println(list);  //链表可以直接输出
        System.out.println("------------------");

        /**
         *测试四: Comparator接口实现 按照数组长度的排序
         *辅助类StringLengthCompare.java
         */
        System.out.println("------------使用Comparator排序数组-----------");
        s = new String[] {"a","abcd","ac","b","ab"};
        UtilSort.bubbleSort(s, new StringLengthCompare());
        System.out.println(Arrays.toString(s)); //按照字符串的长度排序

        /**
         * 使用List + 比较器
         */
        System.out.println("------------使用List + Comparator-----------");
        list = new ArrayList();
        list.add("a");
        list.add("abc");
        list.add("b");
        list.add("ab");
        UtilSort.bubbleSort(list,new StringLengthCompare());
        System.out.println(list);

        System.out.println("------------测试Collections中的sort--------");
        List list2 = new ArrayList();
        list2.add("a");
        list2.add("abc");
        list2.add("b");
        list2.add("ab");
        Collections.sort(list2, new StringLengthCompare()); //按照字符串的长度的排序
        System.out.println(list2);  //链表可以直接输出
        System.out.println("------------------");

        list = new ArrayList();
        list.add("a");
        list.add("abc");
        list.add("b");
        list.add("ab");
        Collections.sort(list);  //默认的比较器
        System.out.println(list);  //链表可以直接输出
        System.out.println("------------------");
    }
}

你可能感兴趣的:(Java容器)