栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

排序之Comparable和Comparator

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

排序之Comparable和Comparator

Comparable和 Comparator这俩接口经常被使用,这里介绍下这俩是什么以及怎么用

Comparable和Comparator一般都是用来排序对象的,
Comparable是内部比较器,Comparator是外部比较器,直接上代码看例子
1.Comparable

Comparable内部比较器,故那个类需要排序自己就实现这个借口

使用方式

1.如果我们想让List按一定方式排序,可以将SortA实现 Comparable接口,重写compareTo(SortA s)方法

@Data
public class SortA implements Serializable, Comparable{
    
  	 @ApiModelProperty("名字")
    private String name;
    @ApiModelProperty("年龄")
    private Integer age;
    
    
    //自定义排序规则
    @Override
    public int compareTo(SortA o) {
        return  this.age - o.getAge(); //升序
        //return this.age.compareTo( o.getAge()); //升序
        //return o.getAge() - this.age; //倒序
        //return o.getAge().compareTo(this.age); //倒序
        //return -1; //自然排序的倒序
        //return 1 或 0; //自然排序
    }
}
public class 排序 {
    public static void main(String[] args) {
		//创造数据
        List listA = new ArrayList<>();
        SortA a1 = new SortA();
        a1.setName("a张三");
        a1.setAge(18);
        SortA a2 = new SortA();
        a2.setName("c李四");
        a2.setAge(16);
        SortA a3 = new SortA();
        a3.setName("b王五");
        a3.setAge(17);
        listA.add(a1);
        listA.add(a2);
        listA.add(a3);
		//调用方法
        testComparable(listA);
    }
  
    public static void testComparable(List listA) {
        //排序方法Collections.sort(List list);
        //内部使用 Arrays.sort(a, (Comparator) c);    
        //所以如果数据是是数组,可以直接用Arrays.sort(数据)来排序
        Collections.sort(listA);
        System.out.println("Comparable排序:" + listA);
        //Comparable排序:[SortA(name=李四, age=16), SortA(name=王五, age=17), SortA(name=张三, age=18)]
    }
}
2.Comparator

我们可以发现Comparable代码侵入性比较强,而且不够灵活,我们同一对象每次排序的规则不可能都一样,那么就可以外部比较器Comparator

使用方式

1.Comparator可以不由SortA实现,可以实现一个SortAComparator排序类

//注意泛型是需要排序的类SortA
public class SortAComparator implements Comparator {

    
    @Override
    public int compare(SortA o1, SortA o2) {
        int sort = o1.getAge() - o2.getAge();
        return sort;
    }
}

Comparable是一个函数式接口,所以可以使用匿名内部类或者Lambda表达式来实现

甚至jdk8以后Comparable提供了很多static方法直接供我们使用

2.直接上代码

public class 排序 {
    public static void main(String[] args) {
		//创造数据
        List listA = new ArrayList<>();
        SortA a1 = new SortA();
        a1.setName("a张三");
        a1.setAge(18);
        SortA a2 = new SortA();
        a2.setName("c李四");
        a2.setAge(16);
        SortA a3 = new SortA();
        a3.setName("b王五");
        a3.setAge(17);
        listA.add(a1);
        listA.add(a2);
        listA.add(a3);
		//调用方法
        testComparator(listA);
    }
  
    public static void testComparator(List listA) {
        //外部比较器,实现Comparator接口
        //1.SortAComparator实现Comparator接口
        listA.sort(new SortAComparator());
        System.out.println(listA);
        //2.使用匿名内部类或Lambda,表达式
        listA.sort(new Comparator() {
            @Override
            public int compare(SortA o1, SortA o2) {
                //年龄倒序
                return o2.getAge() - o1.getAge();
            }
        });
        //3.使用匿名内部类或Lambda或Comparator的静态方法"
        //3.1按照名字正序排序
       	listA.sort(Comparator.comparing(SortA::getName));
        System.out.println(listA);
        //3.2按照名字倒序排序
        listA.sort(Comparator.comparing(SortA::getName).reversed());
        System.out.println(listA);
        listA.sort(Comparator.comparing(SortA::getName,Comparator.reverseOrder()));
        System.out.println(listA);
    }
}
注意多条件情况!!

reversed和Comparator.reverseOrder()反转顺序的时机不同

Comparator.reverseOrder()会立即对此属性排序
reversed()会得到左边的结果后在排序

所以

Comparator.reverseOrder()是只针对当前属性的反转,
reversed()会使左边所有排序反转,注意这一点就行了
上测试~~
public class 排序 {
public static void main(String[] args) {

        List listA = new ArrayList<>();
        SortA a1 = new SortA();
        a1.setName("a");
        a1.setAge(18);
        SortA a2 = new SortA();
        a2.setName("a");
        a2.setAge(19);
        SortA a3 = new SortA();
        a3.setName("b");
        a3.setAge(17);
        SortA a4 = new SortA();
        a4.setName("c");
        a4.setAge(17);
        SortA a5 = new SortA();
        a5.setName("d");
        a5.setAge(15);
        listA.add(a1);
        listA.add(a2);
        listA.add(a3);
        listA.add(a4);
        listA.add(a5);
    	
        moreComparator(listA);
    }


public static void moreComparator(List listA){
        //1.name正序,name一样age正序
        listA.sort(Comparator.comparing(SortA::getName).thenComparing(SortA::getAge));
        System.out.println(listA);
        //2.name倒序,name一样age正序
        listA.sort(Comparator.comparing(SortA::getName).reversed().thenComparing(SortA::getAge));
        System.out.println(listA);     			listA.sort(Comparator.comparing(SortA::getName,Comparator.reverseOrder()).thenComparing(SortA::getAge));
        System.out.println(listA);
        //3.name倒序,name一样age倒序
        listA.sort(Comparator.comparing(SortA::getName).thenComparing(SortA::getAge).reversed());
        System.out.println(listA);
  listA.sort(Comparator.comparing(SortA::getName,Comparator.reverseOrder()).thenComparing(SortA::getAge,Comparator.reverseOrder()));
        System.out.println(listA);
        //4.name正序,name一样age倒序
        listA.sort(Comparator.comparing(SortA::getName).reversed().thenComparing(SortA::getAge).reversed());
        System.out.println(listA);
	listA.sort(Comparator.comparing(SortA::getName).thenComparing(SortA::getAge,Comparator.reverseOrder()));
        System.out.println(listA);
    }
}
注意对象为空或者属性为空的情况
public class 排序 {
    public static void main(String[] args) {

        List listA = new ArrayList<>();
        SortA a1 = new SortA();
        a1.setName("a");
        a1.setAge(18);
        SortA a2 = new SortA();
        a2.setName("a");
        a2.setAge(19);
        SortA a3 = new SortA();
        a3.setName("b");
        a3.setAge(17);
        SortA a4 = new SortA();
        a4.setName("c");
        a4.setAge(17);
        SortA a5 = new SortA();
       // a5.setName("d");
        a5.setAge(15);
        listA.add(a1);
        listA.add(a2);
        listA.add(a3);
        listA.add(a4);
        listA.add(a5);
        listA.add(null);
        
        nullComparator(listA);	
	}
    //如果对象或者属性为空
    public static void nullComparator(List listA){
        //1.如果对象为空
      listA.sort(Comparator.nullsFirst(Comparator.comparing(SortA::getName,Comparator.nullsFirst(Comparator.naturalOrder()))));
        System.out.println(listA);

        //2.如果name为空
        //自然排序
        listA.sort(Comparator.comparing(SortA::getName,Comparator.nullsFirst(Comparator.naturalOrder())));
        listA.sort(Comparator.comparing(SortA::getName,Comparator.nullsFirst(String::compareTo)));
        System.out.println(listA);
        //反转
        listA.sort(Comparator.comparing(SortA::getName,Comparator.nullsFirst(Comparator.reverseOrder())));
        System.out.println(listA);
    }
 
}
总结:

Comparable是内部比较器,Comparator是外部比较器

最推荐使用Comparator接口排序

Comparator提供静态方法很方便,推荐使用,不了解的可以先去学习函数式接口、Lambda、方法引用

Comparator多条件排序时注意Comparator.reverseOrder()和reversed()的使用,

Comparator排序时注意对象和属性可能为空的情况,使用Comparator.nullsFirst()或者Comparator.nullsLast()

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/715914.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号