Java实现有界优先队列

本文依据PriorityQueue实现有界的优先队列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import java.util.*;

/**
* 有界优先队列<br>
* 按照给定的排序规则,排序元素,当队列满时,按照给定的排序规则淘汰末尾元素(去除末尾元素)
*
* @author jimo
* @date 2019/9/16 15:04
*/
public class BoundedPriorityQueue<E> extends PriorityQueue<E> {
/**
* 序列化唯一性
*/
private static final long serialVersionUID = 3794348988671694820L;

/**
* 容量
*/
private int capacity;
/**
* 自定义比较
*/
private Comparator<? super E> comparator;

/**
* 构造
*/
public BoundedPriorityQueue(int capacity) {
this(capacity, null);
}

/**
* 构造
*
* @param capacity 容量
* @param comparator 比较器
*/
public BoundedPriorityQueue(int capacity, final Comparator<? super E> comparator) {
super(capacity, (o1, o2) -> {
int cResult;
if (comparator != null) {
cResult = comparator.compare(o1, o2);
} else {
@SuppressWarnings("unchecked")
Comparable<E> o1c = (Comparable<E>) o1;
cResult = o1c.compareTo(o2);
}

return -cResult;
});
this.capacity = capacity;
this.comparator = comparator;
}

/**
* 加入元素,当队列满时,淘汰末尾元素
*
* @param e 元素
* @return 加入成功与否
*/
@Override
public boolean offer(E e) {
if (size() >= capacity) {
E head = peek();
if (this.comparator().compare(e, head) <= 0) {
return true;
}
//当队列满时,就要淘汰顶端队列
poll();
}
return super.offer(e);
}

/**
* 添加多个元素<br>
* 参数为集合的情况请使用{@link PriorityQueue#addAll}
*
* @param c 元素数组
* @return 是否发生改变
*/
public boolean addAll(E[] c) {
return this.addAll(Arrays.asList(c));
}

/**
* @return 返回排序后的列表
*/
public ArrayList<E> toList() {
final ArrayList<E> list = new ArrayList<>(this);
list.sort(comparator);
return list;
}

@Override
public Iterator<E> iterator() {
return toList().iterator();
}
}