[英]Which Queue implementation to use in Java?
我需要在应用程序中使用FIFO结构。 它最多需要包含5个元素。 我想要一个易于使用的东西(我不在乎并发性)来实现Collection接口。
我尝试了LinkedList,它似乎来自Queue,但似乎不允许我设置其最大容量。 感觉好像我只想要最多5个元素,但尝试添加20个元素,它只会不断增加大小以适合它。 我想要一些可以通过以下方式工作的东西:
XQueue<Integer> queue = new XQueue<Integer>(5); //where 5 is the maximum number of elements I want in my queue.
for (int i = 0; i < 10; ++i) {
queue.offer(i);
}
for (int i = 0; i < 5; ++i) {
System.out.println(queue.poll());
}
打印:
5
6
7
8
9
谢谢
创建自己想要的子类,并覆盖add方法,以便它
(以及构造函数)。
如果您希望在插入时将其阻塞(如果已满),则是另一回事。
看起来您想要的是有限大小的FIFO结构,该结构在添加新项目时会将最旧的项目逐出。 我建议基于循环数组实现的解决方案,在该解决方案中,您应该跟踪队列尾部和队列头的索引,并根据需要(以循环方式)增加它们。
编辑:这是我的实现(请注意,这是一个集合)。 它与您的测试方案配合良好。
public class XQueue <T> extends AbstractQueue<T>{
private T[] arr;
private int headPos;
private int tailPos;
private int size;
@SuppressWarnings("unchecked")
public XQueue(int n){
arr = (T[]) new Object[n];
}
private int nextPos(int pos){
return (pos + 1) % arr.length;
}
@Override
public T peek() {
if (size == 0)
return null;
return arr[headPos];
}
public T poll(){
if (size == 0)
return null;
size--;
T res = arr[headPos];
headPos = nextPos(headPos);
return res;
}
@Override
public boolean offer(T e) {
if (size < arr.length)
size++;
else
if (headPos == tailPos)
headPos = nextPos(headPos);
arr[tailPos] = e;
tailPos = nextPos(tailPos);
return true;
}
@Override
public Iterator<T> iterator() {
return null; //TODO: Implement
}
@Override
public int size() {
return size;
}
}
我没有在API中看到任何类似的限制。 您可以通过使用匿名类功能更改add方法的行为来使用ArrayList:
new ArrayList<Object>(){
public boolean add(Object o){ /*...*/ }
}
也许ArrayBlockingQueue可以解决问题。 看这里 。 尝试这样的事情:
BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(5);
for (int i = 0; i < 10; i++) {
while (!queue.offer(i)) {
queue.poll();
}
}
for (int i = 0; i < 5; i++) {
System.out.println(queue.poll());
}
你有三个选择
1) 子类化一个抽象集合
2)将大小限制为5,并在执行插入操作的代码周围进行逻辑处理。
3)使用LinkedListHashMap可以重写removeEldestEntry(Map.Entry)方法,以强加一个策略,以便在将新映射添加到地图时自动删除陈旧的映射。 (然后,您将使用迭代器来获取值-它将按插入顺序返回)
最好的选择是#1-如果您查看链接,这真的很容易。
您看过Apache Commons Collections库吗? BoundedFifoBuffer
应该完全满足您的需求。
如果我没记错的话,我已经完全使用LinkedList完成了您想要的操作。
您需要做的是检查List的大小,如果它是5,并且要添加对象,则删除第一个元素,如果大小是5,则继续这样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.