3

我正在阅读日志文件,但并非所有行都希望立即处理。我正在使用队列/缓冲区来存储等待处理的行。

定期扫描此队列以查找特定行 - 当找到它们时,它们会从队列中删除(它们可以在队列中的任何位置)。当没有找到特定的行时,将一行一行地从队列的开头取出进行处理。

因此,队列需要以下内容:

  • 能够调整大小(或给人以印象)
  • 从任何地方删除元素
  • 添加元素(将始终位于队列的末尾)
  • 被快速扫描
  • 根据性能,有一个指向上次扫描位置的指针。

我最初编写代码时对 Java 或 API 几乎没有经验,并且只是使用了 ArrayList,因为我知道它会起作用(不一定是因为它是最佳选择)。

随着越来越多的日志需要处理,它的性能现在变得很差——那么,在这种情况下,您建议使用什么集合?也总是有可能写我自己的。

谢谢

4

8 回答 8

6

LinkedHashSet 可能很有趣。它实际上是一个 HashSet,但它还维护一个 LinkedList 以允许可预测的迭代顺序 - 因此也可以用作 FIFO 队列,它的好处是它不能包含重复的条目。

因为它也是一个 HashSet,所以搜索(而不是扫描)可以是 O(1),如果它们可以匹配equals()

于 2008-11-13T15:06:08.263 回答
4

LinkedList 可能是最合适的。它具有所有请求的属性,并允许在恒定时间内从中间删除链接,而不是 ArrayList 所需的线性时间。

如果您有一些特定的策略来查找下一个要删除的元素,那么 PriorityQueue 甚至排序集可能更合适。

于 2008-11-13T09:41:55.570 回答
2

快速扫描通常意味着某种基于哈希的实现,ConcurrentSkipListMap 可能是一个很好的实现。在 containskey、remove 和 get 方法上记录(n),并对其进行排序,以便您可以拥有某种与之相关的优先级。

于 2008-11-13T10:18:37.523 回答
1

我不想对正在读取的行进行排序(它们需要保持原始顺序)。但是,我可能会根据每个记录的行具有的会话 ID 阻止这些行(每个会话有几个记录的行)。

考虑一下,我可能有一个:

HashMap<String,LinkedList<String>>

并提供会话 ID 作为键,并使用属于会话的行填充 LinkedList。

地图将提供一种快速搜索与会话 X 相关的行的方法,然后链表将提供添加/删除行的最佳性能(搜索性能是查找与会话 x 相关的行,因此实际行可以从头到尾读取和删除与会话 x 相关的内容 - 推送/弹出)。

有没有比链表更好的集合来调整大小,在末尾添加行并且总是从头开始?我相信 Queue 集合会扩展链表吗?

于 2008-11-13T13:12:55.340 回答
0

因为您需要从集合中删除和添加元素,并搜索特定值,所以可能更好的结构可能是实现 SortedSet 的东西,例如 TreeSet。此类保证添加、删除和包含的 log(n) 性能。

于 2008-11-13T10:22:42.723 回答
0

我猜有些线程将写入队列,而另一个线程将从中读取。

在这种情况下,您应该查看 java.lang.concurrent 包中的队列。

您可以使用 PriorityBlockingQueue 让它为您排序元素,或者如果您想迭代它并选择自己要删除的元素,则可以使用 LinkedBlockingQueue。

于 2008-11-13T10:44:28.953 回答
0

我同意 AVI 和链表将是你最好的选择。您可以轻松调整大小,快速添加到列表末尾,从任何地方快速删除。搜索不会很快,但不会比任何其他未排序列表差。

于 2008-11-13T15:10:57.240 回答
0

番石榴可能会有所帮助。

Guava 项目包含我们在基于 Java 的项目中依赖的 Google 的几个核心库:集合、缓存、原语支持、并发库、通用注释、字符串处理、I/O 等等。

于 2008-11-21T15:29:46.653 回答