Java 这种LILO最有效的收集方式是什么?

Java 这种LILO最有效的收集方式是什么?,java,data-structures,Java,Data Structures,我正在编写与客户机通信的最近网络消息列表。基本上,我只需要一个列表,它最多可以存储X个消息对象。一旦列表达到所需的大小,列表中最早的(第一个)项应被删除。收藏品需要维持它的秩序,我需要做的就是 反复浏览 在末尾添加一项,然后 如果#2使项目过长,则从开头删除该项目 最有效的结构/数组/集合/方法是什么?谢谢 我不认为LILO是真正的术语……但是你正在寻找一个FIFO队列,你想使用一个。应该是你想要的。你可以使用一个简单的旧ArrayList。 添加时,只需执行(假设ArrayList称为al)

我正在编写与客户机通信的最近网络消息列表。基本上,我只需要一个列表,它最多可以存储X个消息对象。一旦列表达到所需的大小,列表中最早的(第一个)项应被删除。收藏品需要维持它的秩序,我需要做的就是

  • 反复浏览
  • 在末尾添加一项,然后
  • 如果#2使项目过长,则从开头删除该项目

  • 最有效的结构/数组/集合/方法是什么?谢谢

    我不认为LILO是真正的术语……但是你正在寻找一个FIFO队列,你想使用一个。

    应该是你想要的。

    你可以使用一个简单的旧ArrayList。 添加时,只需执行(假设ArrayList称为al)

    您可以使用一个。今天的计算机复制数据的速度如此之快,除非你的列表中可以包含数十亿个元素,否则这无关紧要

    性能信息:复制1000万个元素需要我的双核。因此,如果您的用例没有太大的不同,那么对最佳数据结构的思考甚至是一秒钟都是一种浪费。在这种情况下:您有1000多万个元素,而您的应用程序除了插入和删除元素之外什么都不做。如果以任何方式对插入/删除的元素进行操作,则此操作花费的时间很可能超过插入/删除的成本

    链表乍一看似乎更好,但分配内存时需要更多时间,加上代码更复杂(所有指针都在更新)。所以运行时更糟糕。在Java中使用的唯一优点是类已经实现了队列接口,因此在代码中使用它(使用peek()和pop())更自然

    [编辑]让我们看看效率。什么是效率?最快的算法?使用最少行数的一个(因此有最少的bug)?最容易使用的算法(=开发人员端代码最少+bug更少)?性能最好的算法(并不总是最快的算法)

    让我们看一些细节:LinkedList实现了队列,因此使用列表的代码要简单一些(list.pop()而不是list.remove(0))。但LinkedList将为每个add()分配内存,而ArrayList仅为每N个元素分配一次内存。为了进一步减少这种情况,ArrayList将分配N*3/2个元素,因此随着列表的增长,分配的数量将减少。如果您事先知道列表的大小,ArrayList将只分配一次内存。这也意味着GC需要清理的混乱更少。因此,从性能的角度来看,ArrayList在平均情况下以一个数量级获胜

    只有当多个线程访问数据结构时,才需要同步版本。在Java5中,许多人都看到了速度的显著提高。如果您有多个线程放入和弹出,那么尽管分配性能不好,但在本例中,使用可能是一个选项,因为只要队列大小>=2(在这种特殊情况下,to线程不必访问相同的指针),实现可能会允许同时从两个不同的线程推送和弹出。要确定这一点,唯一的选择是运行探查器并测量哪个版本更快


    也就是说:任何关于绩效的建议90%都是错误的,除非有衡量标准支持。今天的系统已经变得如此复杂,背景中发生的事情如此之多,以至于一个人不可能理解甚至列举所有起作用的因素。

    我认为你想要实现一个
    队列
    ,在那里你可以看到,pull和remove方法的作用就像头部没有任何东西一样,直到计数超过所需的阈值。您可能希望包装一个现有的实现。

    I second@rich adams re:Queue。特别是,由于您提到了对网络消息的响应,我认为您可能需要能够很好地处理并发性的东西。查看。

    基于您的第三个需求,我认为您必须扩展或包装现有的实现,我建议您从开始

    使用任何类型的阻塞队列的其他建议都会使您走上错误的道路。在删除另一个元素之前,阻塞队列将不允许将元素添加到完整队列中。此外,它们在等待该操作发生时阻塞。根据你自己的要求,这不是你想要的行为。您希望在将新元素添加到完整队列时自动删除第一个元素


    围绕ConcurrentLinkedQueue创建一个包装器应该相当简单,它覆盖了检查和容量的方法(您的包装器类将维护容量)。如果它们相等,您的offer方法将需要在添加新元素之前轮询队列以删除第一个元素。

    哈哈,我确实想到了我做错了。不过,我的意思是一样的!:)但我猜这不是最有效的方法?好吧,我已经用一个简单的同步方法对它进行了编程,并且对它的效率很好奇。不过,我会调查一下排队的人,谢谢!我仍然想知道什么是最有效的。我已经知道如何使用ArrayList实现这一点,但这是我希望尽快运行的一个关键部分。通过了解什么比ArrayList更快,我可能会学到一些东西!:)这样看:运行最快+代码行数最少是“最有效的”。经验教训:不要浪费时间寻找“比最好的”更好的解决方案。这就留下了更多的时间去学习重要的事情。谁说我在浪费时间?这个问题使我感兴趣。如果“运行速度最快+代码行数最少”意味着使用的不是
    if (al.size() >= YOUR_MAX_ARRAY_SIZE)
    {
      al.remove(0);
    }