Java中的FIFO类

75

我想通过Java中的一个类来实现FIFO。

是否已经存在这样的类?如果不存在,我该如何实现自己的类呢?

注意:

我在这里找到了一个类:http://www.dcache.org/manuals/cells/docs/api/dmg/util/Fifo.html,但它不包含dmg.util.*。 我不知道是否存在这样一个软件包。

7个回答

136
您正在寻找实现Queue接口的任何类,但排除PriorityQueuePriorityBlockingQueue,因为它们不使用FIFO算法。
可能使用add(将元素添加到末尾)和removeFirst(从队列前面移除并返回元素)的LinkedList是最容易使用的。
例如,这里有一个使用LinkedList来排队和检索圆周率数字的程序:
import java.util.LinkedList;

class Test {
    public static void main(String args[]) {
        char arr[] = {3,1,4,1,5,9,2,6,5,3,5,8,9};
        LinkedList<Integer> fifo = new LinkedList<Integer>();

        for (int i = 0; i < arr.length; i++)
            fifo.add (new Integer (arr[i]));

        System.out.print (fifo.removeFirst() + ".");
        while (! fifo.isEmpty())
            System.out.print (fifo.removeFirst());
        System.out.println();
    }
} 

或者,如果你知道你只想把它当作队列来处理(而不需要链表的额外功能),你可以直接使用Queue接口本身:

import java.util.LinkedList;
import java.util.Queue;

class Test {
    public static void main(String args[]) {
        char arr[] = {3,1,4,1,5,9,2,6,5,3,5,8,9};
        Queue<Integer> fifo = new LinkedList<Integer>();

        for (int i = 0; i < arr.length; i++)
            fifo.add (new Integer (arr[i]));

        System.out.print (fifo.remove() + ".");
        while (! fifo.isEmpty())
            System.out.print (fifo.remove());
        System.out.println();
    }
}

这样做的好处是,您可以将基础的具体类替换为任何提供Queue接口的类,而不必太多修改代码。
基本更改是将fifo的类型更改为Queue并使用remove()而不是removeFirst(),因为后者在Queue接口中不可用。
调用isEmpty()仍然可以,因为它属于Collection接口,而Queue是其派生。

2
为什么不将fifo定义为Queue<Integer>类型呢?针对接口而非具体实现进行编程。 - Adam Parkin
如果您只想以FIFO方式迭代队列中的项目而不实际删除它们,则可以使用for(Object item:queue),它将以FIFO方式迭代它们,至少在JDK 7和ArrayDeQueueLinkedList实现中。 - Ali
3
“你正在寻找实现队列接口的任何类”这句话是不正确的。如果有人想要FIFO,则不应该选择PriorityQueue或者PriorityBlockingQueue,因为它们不支持FIFO;它们有一种不同的排序算法。此外,如果有人想要“一个简单的FIFO队列”,他们可能也不需要SynchronousQueue。可以说,他们甚至不需要任何Blocking队列,虽然这是一个更具争议性的说法。这将选择范围缩小到两个选项:LinkedListArrayDeQueue - ToolmakerSteve
@ClickUpvote - 我在思考那种语法是好事还是坏事。看到那行代码时,我的第一反应是它正在处理那些项目,例如将它们从队列中移除。我认为任何使用该语法的人都应该在该代码行上方放置一个注释,说明这是查看项目而不是删除它们。尽管如此,这是一个很方便的技巧需要知道。 - ToolmakerSteve
@ToolmakerSteve,如果你认为这种语法是在删除东西,那么你一定是Java或Java 7的新手。这种语法在Java中非常常见,可以循环遍历几乎任何东西而不会删除它们。它也比只是循环遍历某些内容的for / while循环更受推荐。 - Ali

19

是的,ArrayDeque和LinkedList都有来自Deque的.push方法,这使它们可用作FIFO堆栈。ArrayDeque更像是一个原始数组,可用作缓冲区,而LinkedList更像是一个数据存储器。 - djangofan
1
@djangofan 栈是后进先出。 - Austin_Anderson

2
队列”是一种先进先出的数据结构。根据您的描述比较模糊,但我猜测您只需要通常与队列结构相关的基本功能。您可以在这里查看如何实现它。
至于您缺少的包,很可能是因为您需要按照那个教程自己下载或创建该包。

1

你不必实现自己的FIFO队列,只需查看接口java.util.Queue及其实现即可。


1

0

-1

现在不确定你们称呼 FIFO 是什么,因为队列是 FILO。但当我还是学生时,我们使用了简单的Stack<E>,包括 pushpoppeek... 它真的很简单,不需要用队列或其他被认可的答案来使它更加复杂。


2
堆栈(Stack)被定义为后进先出的实现,而队列(Queue)的实现默认情况下是先进先出,除非使用比较器进行指示。 - Clement Osei Tano
如果先进后出总是(不)占用相同的槽位,那么我记错了。否则,java.util.Stack就不会以这种方式工作。请参阅:https://docs.oracle.com/javase/7/docs/api/java/util/Stack.html - 3xCh1_23

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接