简体   繁体   English

在Java中使用哪个Queue实现?

[英]Which Queue implementation to use in Java?

I need to use a FIFO structure in my application. 我需要在应用程序中使用FIFO结构。 It needs to have at most 5 elements. 它最多需要包含5个元素。 I'd like to have something easy to use (I don't care for concurrency) that implements the Collection interface. 我想要一个易于使用的东西(我不在乎并发性)来实现Collection接口。

I've tried the LinkedList, that seems to come from Queue, but it doesn't seem to allow me to set it's maximum capacity. 我尝试了LinkedList,它似乎来自Queue,但似乎不允许我设置其最大容量。 It feels as if I just want at max 5 elements but try to add 20, it will just keep increasing in size to fit it. 感觉好像我只想要最多5个元素,但尝试添加20个元素,它只会不断增加大小以适合它。 I'd like something that'd work the following way: 我想要一些可以通过以下方式工作的东西:

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

That'd print: 打印:

5
6
7
8
9

Thanks 谢谢

Create your own subclass of the one you want, and override the add method so that it 创建自己想要的子类,并覆盖add方法,以便它

  • checks if the new object will fit, and fails if not 检查新对象是否适合,否则检查失败
  • calls super.add() 调用super.add()

(and the constructors). (以及构造函数)。

If you want it to block when inserting if full, it is a different matter. 如果您希望在插入时将其阻塞(如果已满),则是另一回事。

Looks like what you want is a limited size FIFO structure, that evicts oldest items when new ones are added. 看起来您想要的是有限大小的FIFO结构,该结构在添加新项目时会将最旧的项目逐出。 I recommend a solution based on a cyclic array implementation, where you should track the index of the queue tail and queue head, and increase them (in cyclic manner) as needed. 我建议基于循环数组实现的解决方案,在该解决方案中,您应该跟踪队列尾部和队列头的索引,并根据需要(以循环方式)增加它们。

EDIT: Here is my implementation (note that it IS a Collection). 编辑:这是我的实现(请注意,这是一个集合)。 It works fine with your test scenario. 它与您的测试方案配合良好。

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

I haven't seen any limitation like that in the API. 我没有在API中看到任何类似的限制。 You can use ArrayList by changing the behavior of the add method with anonymous class feature: 您可以通过使用匿名类功能更改add方法的行为来使用ArrayList:

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

Perhaps an ArrayBlockingQueue might do the trick. 也许ArrayBlockingQueue可以解决问题。 Look here . 这里 Try something like this: 尝试这样的事情:

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

You have three choices 你有三个选择

1) Subclass an Abstract Collection 1) 子类化一个抽象集合

2) Limit the size to five and do the logic around the code where you are doing the insert. 2)将大小限制为5,并在执行插入操作的代码周围进行逻辑处理。

3) Use LinkedListHashMap The removeEldestEntry(Map.Entry) method may be overridden to impose a policy for removing stale mappings automatically when new mappings are added to the map. 3)使用LinkedListHashMap可以重写removeEldestEntry(Map.Entry)方法,以强加一个策略,以便在将新映射添加到地图时自动删除陈旧的映射。 (You would then use an Iterator to get the values - which will be returned in order of insertion) (然后,您将使用迭代器来获取值-它将按插入顺序返回)

Your best bet is #1 - It is real easy if you look at the link. 最好的选择是#1-如果您查看链接,这真的很容易。

Did you have a look at the Apache Commons Collections library? 您看过Apache Commons Collections库吗? The BoundedFifoBuffer should exactly meet your needs. BoundedFifoBuffer应该完全满足您的需求。

If I remember correctly, I've done exactly what you want using a LinkedList. 如果我没记错的话,我已经完全使用LinkedList完成了您想要的操作。

What you need to do is check the size of the List, if it's 5 and you want to add objects, just delete the first element and keep doing so if the size is 5. 您需要做的是检查List的大小,如果它是5,并且要添加对象,则删除第一个元素,如果大小是5,则继续这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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