Comparator比较器和Comparable接口

一.Comparable接口

请实现Comparable接口,实现一个List集合中的People 按姓名排序:

public class People implements Comparable{

    public People(String name,int age){
        this.age = age;
        this.name = name;
    }
    public int age;
    public String name;

    public int compareTo(Object obj) {
        People people = (People) obj;
        return name.compareTo(people.name);
    }

}

哈哈,我来看下 str.comPareto(str)里面到底是怎么实现的:

    /*
     * @param   anotherString   the {@code String} to 
     * be compared.is equal to
     * this string; a value less than {@code 0} if this string
     * is lexicographically less than the string argument; and     
     * a value greater than {@code 0} if this string is
     * lexicographically greater than the string argument.
     */
    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) { //从0开始,不能超过小长度lim
            char c1 = v1[k];//从新装载,代码六六的
            char c2 = v2[k];//六六的
            if (c1 != c2) {  
                return c1 - c2;//返回字符之间的差值
            }
            k++;
        }
        return len1 - len2;//返回字符之间的长度
        //告诉我们一个道理,同样长的字符,谁的字符顺序在后就在后,
        // 例如:"abc"和"abf",那么"abf"肯定在后了。
        // 还比如:"abcd"和"abcda",那"abcda"肯定在后面
    }

好了,不扯了,解题要紧。

package com.test.comparator;

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

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        List list  = new ArrayList();
        People peoplea = new People("a", 15);
        People peoplec = new People("abc", 14);
        People peoplef = new People("abf", 16);
        People peopleg = new People("g", 19);
        People peopleh = new People("h", 10);
        People peoplet = new People("t", 8);
        People peopleb = new People("b", 17);
        list.add(peoplea);
        list.add(peoplec);
        list.add(peoplef);
        list.add(peopleg);
        list.add(peopleh);
        list.add(peoplet);
        list.add(peopleb);

        Collections.sort(list);
        for (int i = 0; i<list.size();i++){
            System.out.println(
            " name = "+((People)list.get(i)).name+
            " age = " ((People)list.get(i)).age);
        }


    }

}

输出结果:
name = a age = 15
name = abc age = 14
name = abf age = 16
name = b age = 17
name = g age = 19
name = h age = 10
name = t age = 8


那按年龄排序呢?
根据 compareTo 中的原理,return c1-c2,哈哈,看下面实现。
package com.test.comparator;

public class People implements Comparable{

    public People(String name,int age){
        this.age = age;
        this.name = name;
    }
    public int age;
    public String name;

    public int compareTo(Object obj) {
        People people = (People) obj;
        return age-people.age;//改动这里
    }

}
输出结果:
name = t age = 8
name = h age = 10
name = abc age = 14
name = a age = 15
name = abf age = 16
name = b age = 17
name = g age = 19


二.使用Comparator比较器
接题:使用comparator对List中的按姓名排序,姓名相等的按年龄排序。
有木有挑战。看实现:

package com.test.comparator;

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

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        List list  = new ArrayList();
        People peoplea = new People("a", 15);
        People peoplec = new People("abc", 14);
        People peoplef = new People("abf", 16);
        People peopleg = new People("a", 19);//改动
        People peopleh = new People("h", 10);
        People peoplet = new People("a", 8);//改动
        People peopleb = new People("a", 17);//改动
        list.add(peoplea);
        list.add(peoplec);
        list.add(peoplef);
        list.add(peopleg);
        list.add(peopleh);
        list.add(peoplet);
        list.add(peopleb);

        Collections.sort(list,new MyComparator());//改动
        for (int i = 0; i<list.size();i++){
            System.out.println(
            "name = "+((People)list.get(i)).name+
            "age = "+((People)list.get(i)).age);
        }


    }

}
package com.test.comparator;

import java.util.Comparator;

public class MyComparator implements Comparator{
    public int compare(Object obj1, Object obj2) {
        People p1 = (People) obj1;
        People p2 = (People) obj2;
        int result =  p1.name.compareTo(p2.name);
        if (result > 0){ //字母顺序
            return 1;
        } else if (result == 0){ //姓名相同
            if (p1.age == p2.age){
                return 0;
            } else if (p1.age > p2.age){ // 从小到大
                return 1;
            } else {
                return -1;
            }
            //return 0;
        } else {
            return -1;
        }

    }

}

输出结果:
name = a age = 8
name = a age = 15
name = a age = 17
name = a age = 19
name = abc age = 14
name = abf age = 16
name = h age = 10

我还要想同名的 年龄按倒序排,怎么弄?
看下Comparator源码

    public interface Comparator<T> {
    /*
     * @param o1 the first object to be compared.
     * @param o2 the second object to be compared.
     * @return a negative integer, zero, or a positive 
     * integer as the first argument is less than, equal to, 
     * or greater than the second.
     * @throws NullPointerException if an argument is null and    
     * this comparator does not permit null arguments
     * @throws ClassCastException if the arguments' types 
     * prevent them from being compared by this comparator.
     */
    int compare(T o1, T o2);

a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
负整数 0 正整数 对应小于 等于 大于

也就是说,当 o1 < o2 return -1,;o1 == o2 retrun 0 ;
o1 >o3 return 1;
隐藏一句话:按照此返回的话,集合正序排序,从小到大,如果要从大到小,o1 < o2 return 1 (改动);o1 == o2 retrun 0 ;
o1 >o3 return -1(改动); 即可

package com.test.comparator;

import java.util.Comparator;

public class MyComparator implements Comparator{
    public int compare(Object obj1, Object obj2) {
        People p1 = (People) obj1;
        People p2 = (People) obj2;
        int result =  p1.name.compareTo(p2.name);
        if (result > 0){
            return 1;
        } else if (result == 0){
            if (p1.age == p2.age){
                return 0;
            } else if (p1.age > p2.age){
                return -1; //改动
            } else {
                return 1;//改动
            }
        } else {
            return -1;
        }

    }

}

输出结果:

name = a age = 19
name = a age = 17
name = a age = 15
name = a age = 8
name = abc age = 14
name = abf age = 16
name = h age = 10

总结一下:实现排序有两种方式,一种是实现Comparable接口,还有就是实现 Comparator比较器。第一种没有第二种灵活,主要体现在 比较多个参数,比如比完姓名还要比年龄,还体现在顺序和倒序上面,Comparator比较器可以灵活切换倒序和顺序! (> return 1; < return -1; = return 0)

完毕,谢谢!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值