PriorityQueue如何传入比较器实现大小堆~

关于priorityQueue:

1、priorityQueue里不能放null,要放可以比较的值

class Card {
    public int rank; // 数值
    public String suit; // 花色
    public Card(int rank, String suit) {
        this.rank = rank;
        this.suit = suit;
    }
}
public class TestDemo {
    public static void main(String[] args) {
        PriorityQueue<Card> priorityQueue=new PriorityQueue<>();//默认是小根堆
        priorityQueue.offer(new Card(1,"♥"));
        priorityQueue.offer(null);//会报错,priorityQueue里不能放null,要放可以比较的值
    }
}

2、priorityQueue底层数组的初始容量为11

扩容时:若原先容量小于64——》新容量=原先容量*2+2

              若原先容量大于64——》新容量=原先容量*1.5


 一、关于对象的比较 

1、用implements实现比较接口Comparable(要重写compareTo方法)

缺点:对类的侵入性太强了,一旦写好了根据那种规则进行比较就不能轻易修改了

class Card implements Comparable<Card> {//要想比较自定义类型,需要自己重写比较方法
    public int rank; // 数值
    public String suit; // 花色
    public Card(int rank, String suit) {
        this.rank = rank;
        this.suit = suit;
    }

public int compareTo(Card o) {//重写比较方法
        return this.rank-o.rank;//默认小堆的比较方法
      //return o.rank-this.rank;大堆的比较方法
    }


 public static void main(String[] args) {
        Card card1=new Card(2,"♥");
        Card card2=new Card(1,"♥");
        System.out.println(card1.compareTo(card2));//比较大小
    }

2、单独实现一个比较器Comparator(需要写比较方法compare

class Card {
    public int rank; // 数值
    public String suit; // 花色

    public Card(int rank, String suit) {
        this.rank = rank;
        this.suit = suit;
    }


class RankComparator implements Comparator<Card> {//单独实现一个比较器

        @Override
        public int compare(Card o1, Card o2) {//写一个比较方法
            return o1.rank-o2.rank;
        }
 }

 public static void main(String[] args) {
        Card card1=new Card(2,"♥");
        Card card2=new Card(1,"♥");
        RankComparator rankComparator=new RankComparator();//实例化比较器对象
        int ret=rankComparator.compare(card1,card2);//根据对象调用方法来比较大小
        System.out.println(ret);
}

3、用equals比较对象:只能知道是否相同,相同返回true,不同返回false

public static void main(String[] args) {
            Card card1=new Card(1,"♥");
            Card card2=new Card(1,"♥");
            System.out.println(card1.equals(card2));//输出false,因为没有重写equals方法,默认调用object的equals方法,比较的是地址
        }



//要想根据花色和数字来判断两张牌的内容是否相同,需要重写equals方法
class Card {
    public int rank; // 数值
    public String suit; // 花色

    public Card(int rank, String suit) {
        this.rank = rank;
        this.suit = suit;
    }

    @Override重写的equals方法
    public boolean equals(Object o) {
        if (this == o) return true;//如果引用的是同一个对象,返回true
        if (o == null || getClass() != o.getClass()) return false;//getClass() != o.getClass()看是否为同一个类型,不能Card根Person比较
        Card card = (Card) o;//因为o是object类型,需要强转
        return rank == card.rank && Objects.equals(suit, card.suit);
    }

    @Override
    public int hashCode() {
        return Objects.hash(rank, suit);
    }
}

注意:如果是自定义类型,若要根据内容判断是否相同,需要重写equals方法


二、对于 priorityQueue如何自定义小堆还是大堆,只需要创建时传入一个小堆的比较器,或大堆的比较器即可

//法一:直接实现一个比较器,然后再使用队列时传入比较器
class RankComparator implements Comparator<Card> {//单独实现一个比较器

        @Override
        public int compare(Card o1, Card o2) {//写一个比较方法
            return o1.rank-o2.rank;//实现小堆,要实现大堆,则return o2.rank-o1.rank;
        }
    }



public static void main(String[] args) {
        Card card1=new Card(2,"♥");
        Card card2=new Card(1,"♥");

        RankComparator rankComparator=new RankComparator();//实例化比较器
        PriorityQueue<Card> priorityQueue=new PriorityQueue<>(rankComparator);//传入比较器,就可以根据比较器来自定义小堆比较还是大堆比较了

        priorityQueue.offer(card1);
        priorityQueue.offer(card2);
        System.out.println(priorityQueue);
}


//法二:用内部类的方法,再使用队列时传入一个内部类,在内部类里写一个比较方法
public static void main(String[] args) {
        Card card1=new Card(2,"♥");
        Card card2=new Card(1,"♥");
        
        PriorityQueue<Card> priorityQueue=new PriorityQueue<>(new Comparator<Card>() {
            @Override
            public int compare(Card o1, Card o2) {
                return o1.rank-o2.rank;//实现小堆,要实现大堆,则return o2.rank-o1.rank;
            }
        });
        
        priorityQueue.offer(card1);
        priorityQueue.offer(card2);
        System.out.println(priorityQueue);
        
    }

//法三:用lambda表达式实现内部类

PriorityQueue<Card>priorityQueue1=new PriorityQueue<>((x,y)->{return x.rank-y.rank;});



三、PriorityQueue底层插入数据操作过程

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值