在Java中使用哪个队列实现?

时间:2010-04-17 17:16:22

标签: java queue

我需要在我的应用程序中使用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

由于

7 个答案:

答案 0 :(得分:3)

创建自己想要的子类,并覆盖add方法以便

  • 检查新对象是否适合,如果不是
  • 则失败
  • 调用super.add()

(和构造函数)。

如果你想在插入时阻止它,如果已满,则是另一回事。

答案 1 :(得分:2)

看起来你想要的是一个有限大小的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;
    }
}

答案 2 :(得分:2)

我没有看到像API那样的限制。您可以通过使用匿名类功能更改add方法的行为来使用ArrayList:

new ArrayList<Object>(){
    public boolean add(Object o){ /*...*/ }
}

答案 3 :(得分:1)

也许ArrayBlockingQueue可能会成功。看here。尝试这样的事情:

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());
}

答案 4 :(得分:1)

您有三个选择

1)Subclass an Abstract Collection

2)将大小限制为5,并在执行插入的代码周围执行逻辑。

3)使用LinkedListHashMap可以重写removeEldestEntry(Map.Entry)方法,以强制在将新映射添加到地图时自动删除过时映射的策略。 (然后,您将使用Iterator获取值 - 将按插入顺序返回)

你最好的选择是#1 - 如果你看一下链接就很容易了。

答案 5 :(得分:1)

你看过Apache Commons Collections图书馆了吗? BoundedFifoBuffer应该完全符合您的需求。

答案 6 :(得分:0)

如果我没记错的话,我已经使用LinkedList做了你想要的。

您需要做的是检查List的大小,如果它是5并且您想要添加对象,只需删除第一个元素并在大小为5时继续这样做。