java比较器,匿名比较器,lambda比较器,优先级队列的使用

java有一个比较器接口Comparator,里面有一个compare方法。
比较函数有两个参数a,b;返回a-b就是升序,返回b-a就是降序。不过最好用比较,不要用相减。

使用场景:

  1. Arrays里面有一个sort(T[],Comparator)可以根据比较器对数组的数据进行排序。排序二维数组是最好用的选择。
    例如每个人都有身高和体重[h,w],有n个人,就可以弄成二维数组。然后按照身高或者体重进行排序。
  2. 数组降序排序也要使用比较器,根据比较器进行排序。
  3. 优先级队列里面也要使用比较器。

//points是一个n*2的数组。
 public static void findMinArrowShots(int[][] points) {
 		//lambda写法,比较简洁,不过存在溢出危险,最好使用比较,升序,把后面改成b[0]-a[0]就是降序
 		//这里的a,b都是一维数组,因为points是二维数组
		Arrays.sort(points,(a,b)->(a[0]-b[0]));
		
		//lambda写法,该方式不会溢出,虽然写多一点,推荐该方式,升序,把判断的>,<转一下就是降序
		Arrays.sort(points,(a,b)->{
            if(a[0]>b[0]){
                return 1;
            }else if(a[0]<b[0]){
                return -1;
            }else{
                return 0;
            }
        });
        
        /**
         * 匿名内部类写法
         * 该方式会直接获取points里面的节点
         */
        Arrays.sort(points, new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                /**
                这个是按points[i][0]从小到大排序,如果要从大到小,只需要把判断的符合改一下
                 * 这里的每个参数就是二维数组里面的一个一维数组
                 * o1[]就是points[i]
                 */
                if(o1[0]>o2[0]){
                    return 1;
                }else if(o1[0]<o2[0]){
                    return -1;
                }else{
                    return 0;
                }
            }
        });
        
        /**
         * 这是先创建比较器,然后再将比较器对象作为参数放到函数中
         * 这里能使用points是因为在points的作用域里面
         */
        Comparator comparator=new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                if(points[o1][0]>points[o2][0]){
                    return 1;
                }else if(points[o1][0]<points[o2][0]){
                    return -1;
                }else{
                    return 0;
                }
            }
        };
        PriorityQueue queue1=new PriorityQueue(comparator);
        for(int i=0;i<points.length;i++){
            queue1.offer(i);
        }
        
        /**
         * lambda表达式写法
         * 个人比较喜欢这种。
         */
        PriorityQueue<Integer> queue=new PriorityQueue<>((a, b)-> {
            if(points[a][0]>points[b][0]){//
                return 1;
            }else if(points[a][0]<points[b][0]){
                return -1;
            }
            return 0;
        });

        for(int i=0;i<points.length;i++){
            queue.offer(i);
        }
    }

lambda写法

最近学了lambda表达式的写法,真是太酷啦,代码简洁多了。不过注意,这种写法只支持对象。
如果只是简单的比较逻辑,可以用Comparator.comparing(类名::获取字段方法名),这个是按照该字段升序排序比较器
Comparator.comparing(类名::获取字段方法名,Comparator.reverseOrder()),这个是按照该字段降序排序比较器
Comparator.comparing(类名::获取字段方法名1,Comparator.reverseOrder()).thenComparing(类名::获取字段方法名2),这个是按照字段1降序,如果字段1一样,再按照字段2升序排序比较器

import java.util.*;
import java.util.stream.Collectors;


/**
 * @ClassName: Test
 * @Author: zengjingchao
 * @Date: 2023/6/1 14:18
 * @Description:
 **/
public class Test {
    public static void main(String[] args) throws InterruptedException {
        List<TTT> list=new ArrayList<>();
        list.add(new TTT(new Date()));
        Thread.sleep(1000);
        list.add(new TTT(new Date()));
        list.add(new TTT(new Date()));
        Thread.sleep(1000);
        list.add(new TTT(new Date()));
        list.add(new TTT(new Date()));
        //最大值,默认就是按照比较器的比较逻辑,取最后一个
        Optional<TTT> max = list.stream().max(Comparator.comparing(TTT::getA));
        System.out.println(max.get().getA());
        System.out.println("----------");

        for(TTT ttt:list){
            System.out.println(ttt.getA());
        }
        System.out.println("---------");
        //降序,因为在比较器加多了一个参数Comparator.reverseOrder(),代表反转,推荐这种写法
        List<TTT> collect = list.stream().sorted(Comparator.comparing(TTT::getA, Comparator.reverseOrder())).collect(Collectors.toList());
        for(TTT ttt:collect){
            System.out.println(ttt.getA());
        }
 		//按照a时间降序,如果时间相同,则按照b升序排,这个是后面加上的,没有跑
        collect = list.stream().sorted(Comparator.comparing(TTT::getA, Comparator.reverseOrder()).thenComparing(TTT::getB)).collect(Collectors.toList());
        for(TTT ttt:collect){
            System.out.println(ttt.getA());
        }

    }
    
}
//实体类
public class TTT {
    private Date a;

    public TTT(Date a) {
        this.a = a;
    }

    public Date getA() {
        return a;
    }

    public void setA(Date a) {
        this.a = a;
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值