我正在寻找Java中的快速queue
实现。我看到LinkedList
实现了Queue
接口,但它只能跟LinkedList
一样快吗?有没有办法让队列更快,尤其是add
(我只需要poll
,add
并检查empty
)。
我可能还需要一个PriorityQueue
但还没有。
答案 0 :(得分:29)
如果多个线程要访问队列,请考虑使用ArrayBlockingQueue
。否则,请查看ArrayDeque
。来自ArrayDeque
API:
这门课的速度可能比 堆叠用作堆栈时,速度更快 用作队列时的LinkedList。
具体而言,如果现有阵列具有足够的容量,则基于阵列的队列实现可减少调整基础阵列大小的需要,从而使队列的添加速度通常快于LinkedList
。请注意ArrayBlockingQueue
是一个有限的实现,而ArrayDeque
将根据需要调整大小。
另一方面,LinkedList
通常会提供更紧凑的表示,特别是在队列增长和缩小的情况下。例如,如果您向ArrayDeque
添加了10,000,000个元素,然后删除了9,999,999个元素,则基础数组的长度仍为10,000,000,而LinkedList
则不会遇到此问题。
实际上,对于非阻塞队列的单线程访问,我倾向于LinkedList
。我认为性能差异是如此可以忽略不计,你无论如何都不会注意到它们之间的区别。
答案 1 :(得分:28)
我看到LinkedList实现了Queue接口,但它只会和LinkedList一样快吗?
注意源代码,LinkedList对于Queue.add,Queue.poll和Queue.peek操作是O(1)。
我希望它足够快。
答案 2 :(得分:6)
如果链接列表的性能确实存在问题,则另一种方法是在数组中实现“循环队列”,即在添加和删除条目时开始和结束点移动的队列。如果你关心,我可以提供更多细节。当我使用没有集合库的语言时,这就是我总是实现队列的方式,因为它比链表更容易编写而且速度更快。但是对于内置的集合,在特殊情况下编写和调试我自己的集合的努力在99%的情况下都不值得给它带来麻烦:当它已经编写完成时,我可以用不同的方式写出它的速度以Java的方式重写它几乎是一个无关紧要的事实。任何性能提升都可能太小而不值得麻烦。我对现有的集合进行子类型化以获得我偶尔需要的特殊行为,但是我很难想到我最后一次从头开始编写它。
答案 3 :(得分:4)
您可能需要查看介绍GapList
的{{3}}。这个新的列表实现结合了ArrayList
和LinkedList
的优势。
因此它实现了Deque
接口,但也可以像上面提到的ArrayDeque
那样进行预设。此外,您还可以免费获得List
界面的所有可能性。
答案 4 :(得分:1)
从非常简单的旋转队列实现开始,采用“C / C ++”态度和固定大小。
class SimpleQueue<E>
{
int index = 0;
int head = 0;
int size = 100;
int counter = 0;
E[] data ;
@SuppressWarnings("unchecked")
SimpleQueue()
{
data = (E[]) new Object[size];
}
public void add(E e)
{
data[index]=e;
index=(index+1)%size;
counter++;
}
public E poll()
{
E value = data[head];
head=(head+1)%size;
counter--;
return value;
}
public boolean empty()
{ return counter==0; }
//Test
public static void main(String[] args)
{
SimpleQueue<Integer> s = new SimpleQueue<Integer>();
System.out.println(s.empty());
for(int i=0; i< 10; i++)
s.add(i);
System.out.println(s.empty());
for(int i=0; i<10; i++)
System.out.print(s.poll()+",");
System.out.println("\n"+s.empty());
}
}
然后改进它。