繁体   English   中英

在Java中使用哪个Queue实现?

[英]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方法,以便它

  • 检查新对象是否适合,否则检查失败
  • 调用super.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM