Comparable接口和Comparator比较器学习


在这里插入图片描述

类对象实现Comparable接口

创建实现自己的实现类的排序,这种情况下需要将这个实现类继承Comparable接口,并重写compareTo()方法来定义排序的顺序------减法的顺序。

例如:Node类继承了Comparable接口


class Node implements Comparable<Node>{
    int value;
    Node left;
    Node right;

    public Node(int value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "Node{" +
                "value=" + value +
                '}';
    }

    @Override
    public int compareTo(Node o) {
        return this.value-o.value;//实现从小到大排列
    }
}

将这个类封装在一个容器内,例如:

数组,调用Arrays.sort()来实现排序

		int[] arr={13,7,8,3,29,6,1};
        Node[] nrr=new Node[7];
        for (int i = 0; i < arr.length; i++) {
            nrr[i]=new Node(arr[i]);
        }
        Arrays.sort(nrr);
        System.out.println(Arrays.toString(nrr));

在这里插入图片描述

集合,调用Collections.sort()来实现排序

        int[] arr={13,7,8,3,29,6,1};

        List<Node> nodes=new ArrayList<>();
        for (int i = 0; i < arr.length; i++) {
            nodes.add(new Node(arr[i]));
        }
        Collections.sort(nodes);
        System.out.println(nodes.toString());
        

比较器Comparator接口的实现

Arrays.sort(T[] a, Comparator<? super T> c)

实现自定义排序方式(需要重写compare方法)–例如对矩阵的行向量按照每个向量的第一个元素进行排序

        int[][] t=new int[4][2];
        t[0][0]=3;
        t[1][0]=2;
        t[2][0]=4;
        t[3][0]=5;
        Arrays.sort(t, new Comparator<int[]>(){
            @Override
            public int compare(int[] o1, int[] o2) {
                return o1[0]-o2[0];
            }
        });

        for (int j = 0; j < t.length; j++) {
            System.out.println(Arrays.toString(t[j]));

        }

在这里插入图片描述

Collections.sort(List list, Comparator<? super T> c)

实现对列表排序

        List<int[]> list=new ArrayList<>();
        list.add(new int[]{10,20});
        list.add(new int[]{10,10});
        list.add(new int[]{17,19});
        list.add(new int[]{10,19});
        System.out.println("排序前");
        for (int[] ints : list) {
            System.out.println(ints[0]+" "+ints[1]);
        }
        Collections.sort(list, new Comparator<int[]>() {
            //优先按照数组的序号1排序,相等的话按照序号0排序
            @Override
            public int compare(int[] o1, int[] o2) {
                if(Integer.compare(o1[1],o2[1])==0){
                    return Integer.compare(o1[0],o2[0]);
                }else{
                    return Integer.compare(o1[1],o2[1]);
                }
            }
        });
        System.out.println("排序后");
        for (int[] ints : list) {
            System.out.println(ints[0]+" "+ints[1]);
        }

在这里插入图片描述

现有API进行数组的降序排列

注意这个数组必须得是引用类型的才能使用(int[] 不行必须得是integer[])才能使用
在这里插入图片描述

在这里插入图片描述

PriorityQueue的构造函数利用comparator接口实现自定义的排序优先队列(实现小顶堆)

力扣题目–347. 前 K 个高频元素

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        Map<Integer, Integer> occurrences = new HashMap<Integer, Integer>();
        for (int num : nums) {
            occurrences.put(num, occurrences.getOrDefault(num, 0) + 1);
        }

        // int[] 的第一个元素代表数组的值,第二个元素代表了该值出现的次数
        //这个小顶堆(升序排列)装的是一个个的数组,按照数组的第二个元素进行排序
        PriorityQueue<int[]> queue = new PriorityQueue<int[]>(new Comparator<int[]>() {
            public int compare(int[] m, int[] n) {
                return m[1] - n[1];
            }
        });

         //遍历map的键值对集合,进行重新封装为数组,来加入小顶堆中
        for (Map.Entry<Integer, Integer> entry : occurrences.entrySet()) {
            int num = entry.getKey();
            int count = entry.getValue();


            //如果尺寸等于k,需要可能“入一个出一个”保持k这个大小
            if (queue.size() == k) {
                //如果这个元素比堆顶(最小的)都小,不用入堆了
                if (queue.peek()[1] < count) {
                    queue.poll();
                    queue.offer(new int[]{num, count});
                }

             //尺寸够够的直接入堆   
            } else {
                queue.offer(new int[]{num, count});
            }
        }

        int[] ret = new int[k];
        for (int i = k-1; i >=0; i--) {
            ret[i] = queue.poll()[0];
        }
        return ret;
    }
}

注意为了防止溢出(int类型的数值范围,最大减去最小数,显然得到的结果已经溢出了),尽量不要直接用两个数相减的,应该直接使用if判断语句来直接比较两个数的大下来判断返回值到底是0,1,-1
力扣这道题我悟了!!!
在这里插入图片描述
这个是Integer.compare()的源码:
在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值