pythonqueue的用法_使用PriorityQueue

我们知道,Queue是一个先进先出(FIFO)的队列。

在银行柜台办业务时,我们假设只有一个柜台在办理业务,但是办理业务的人很多,怎么办?

可以每个人先取一个号,例如:A1、A2、A3……然后,按照号码顺序依次办理,实际上这就是一个Queue。

如果这时来了一个VIP客户,他的号码是V1,虽然当前排队的是A10、A11、A12……但是柜台下一个呼叫的客户号码却是V1。

这个时候,我们发现,要实现“VIP插队”的业务,用Queue就不行了,因为Queue会严格按FIFO的原则取出队首元素。我们需要的是优先队列:PriorityQueue。

PriorityQueue和Queue的区别在于,它的出队顺序与元素的优先级有关,对PriorityQueue调用remove()或poll()方法,返回的总是优先级最高的元素。

要使用PriorityQueue,我们就必须给每个元素定义“优先级”。我们以实际代码为例,先看看PriorityQueue的行为:

import java.util.PriorityQueue;

import java.util.Queue;

----

public class Main {

public static void main(String[] args) {

Queue q = new PriorityQueue<>();

// 添加3个元素到队列:

q.offer("apple");

q.offer("pear");

q.offer("banana");

System.out.println(q.poll()); // apple

System.out.println(q.poll()); // banana

System.out.println(q.poll()); // pear

System.out.println(q.poll()); // null,因为队列为空

}

}

我们放入的顺序是"apple"、"pear"、"banana",但是取出的顺序却是"apple"、"banana"、"pear",这是因为从字符串的排序看,"apple"排在最前面,"pear"排在最后面。

因此,放入PriorityQueue的元素,必须实现Comparable接口,PriorityQueue会根据元素的排序顺序决定出队的优先级。

如果我们要放入的元素并没有实现Comparable接口怎么办?PriorityQueue允许我们提供一个Comparator对象来判断两个元素的顺序。我们以银行排队业务为例,实现一个PriorityQueue:

import java.util.Comparator;

import java.util.PriorityQueue;

import java.util.Queue;

----

public class Main {

public static void main(String[] args) {

Queue q = new PriorityQueue<>(new UserComparator());

// 添加3个元素到队列:

q.offer(new User("Bob", "A1"));

q.offer(new User("Alice", "A2"));

q.offer(new User("Boss", "V1"));

System.out.println(q.poll()); // Boss/V1

System.out.println(q.poll()); // Bob/A1

System.out.println(q.poll()); // Alice/A2

System.out.println(q.poll()); // null,因为队列为空

}

}

class UserComparator implements Comparator {

public int compare(User u1, User u2) {

if (u1.number.charAt(0) == u2.number.charAt(0)) {

// 如果两人的号都是A开头或者都是V开头,比较号的大小:

return u1.number.compareTo(u2.number);

}

if (u1.number.charAt(0) == 'V') {

// u1的号码是V开头,优先级高:

return -1;

} else {

return 1;

}

}

}

class User {

public final String name;

public final String number;

public User(String name, String number) {

this.name = name;

this.number = number;

}

public String toString() {

return name + "/" + number;

}

}

实现PriorityQueue的关键在于提供的UserComparator对象,它负责比较两个元素的大小(较小的在前)。UserComparator总是把V开头的号码优先返回,只有在开头相同的时候,才比较号码大小。

上面的UserComparator的比较逻辑其实还是有问题的,它会把A10排在A2的前面,请尝试修复该错误。

小结

PriorityQueue实现了一个优先队列:从队首获取元素时,总是获取优先级最高的元素。

PriorityQueue默认按元素比较的顺序排序(必须实现Comparable接口),也可以通过Comparator自定义排序算法(元素就不必实现Comparable接口)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值