Java数据结构

Java数据结构,java,data-structures,Java,Data Structures,我正在寻找一种像队列一样的数据结构,这样我就可以拥有先进先出的行为,但理想情况下,我还可以像使用HashMap一样,以恒定时间查看队列中是否存在元素,而不是使用LinkedList得到的线性时间 我认为LinkedHashMap可以完成这项工作,但尽管我可以制作一个迭代器,只需获取并删除迭代的第一个元素,就可以生成一种poll()方法,但我想知道是否有更好的方法 提前非常感谢我不知道是否有什么东西,但您可以轻松创建一个由队列和哈希集组成的复合对象。所有修改操作都需要同时在两个集合上进行,以使它们

我正在寻找一种像队列一样的数据结构,这样我就可以拥有先进先出的行为,但理想情况下,我还可以像使用HashMap一样,以恒定时间查看队列中是否存在元素,而不是使用LinkedList得到的线性时间

我认为LinkedHashMap可以完成这项工作,但尽管我可以制作一个迭代器,只需获取并删除迭代的第一个元素,就可以生成一种poll()方法,但我想知道是否有更好的方法


提前非常感谢

我不知道是否有什么东西,但您可以轻松创建一个由
队列
哈希集
组成的复合对象。所有修改操作都需要同时在两个集合上进行,以使它们保持同步。然后,您可以使用集合进行查找,这应该是非常快的。

我不知道是否存在某些内容,但您可以轻松创建一个由
队列和
哈希集组成的复合对象。所有修改操作都需要同时在两个集合上进行,以使它们保持同步。然后,您可以使用该集合进行快速查找。

当您需要两个集合的行为时,通常需要维护两个集合。一种简单的方法是拥有一个队列和一个HashSet,当您从队列中删除时,总是在HashMap中执行add-to和remove

另一种方法是使用LinkedHashSet。这将保留添加元素的顺序,并且每次都可以删除第一个/最早的元素

第三种选择是只使用队列。虽然您可能喜欢O(1)查找时间,但您可能会发现它足够快,只需搜索每个元素即可满足您的要求。这可能比您预期的要快得多。i、 e.1000个元素应小于10微秒

编辑:我同意当你不知道长度时,两个系列是最好的

然而,向您展示暴力搜索也可以很快。要寻找的最慢的对象是不存在的对象。(因为它必须比较每个元素)


您可能需要针对您的数据类型进行测试,因为相等时间()和队列大小可能会有所不同,但您可能会惊讶于在10微秒内所做的事情,而且这可能足够快。

通常,当您想要两个集合的行为时,您需要维护两个集合。一种简单的方法是拥有一个队列和一个HashSet,当您从队列中删除时,总是在HashMap中执行add-to和remove

另一种方法是使用LinkedHashSet。这将保留添加元素的顺序,并且每次都可以删除第一个/最早的元素

第三种选择是只使用队列。虽然您可能喜欢O(1)查找时间,但您可能会发现它足够快,只需搜索每个元素即可满足您的要求。这可能比您预期的要快得多。i、 e.1000个元素应小于10微秒

编辑:我同意当你不知道长度时,两个系列是最好的

然而,向您展示暴力搜索也可以很快。要寻找的最慢的对象是不存在的对象。(因为它必须比较每个元素)


您可能需要对您的数据类型进行测试,因为equals()的时间和队列大小可能会有所不同,但您可能会惊讶于在10微秒内完成的操作,而且速度可能足够快。

搜索队列所需的时间在很大程度上取决于内容的equal方法的性能。很抱歉,但是你不可能对这样的手术估计“少于”任何东西。非常感谢你的回复。我想我会尝试使用这两个系列。我认为开销是值得的,因为元素的数量可能非常大。:)@jarnbjo我用“应该是”这个词的意思是,你应该知道你的equals方法的成本是多少,也就是说,它不是RMI调用,你应该通过比较最可能不同的字段来尝试使它变得相当便宜。您可能有一个糟糕的tunes equals方法,并且无法访问equals方法所做的事情,但这不是理想的情况。搜索队列所需的时间在很大程度上取决于内容的equal方法的性能。很抱歉,但是你不可能对这样的手术估计“少于”任何东西。非常感谢你的回复。我想我会尝试使用这两个系列。我认为开销是值得的,因为元素的数量可能非常大。:)@jarnbjo我用“应该是”这个词的意思是,你应该知道你的equals方法的成本是多少,也就是说,它不是RMI调用,你应该通过比较最可能不同的字段来尝试使它变得相当便宜。您可能有一个糟糕的tunes equals方法,并且无法访问equals方法所做的事情,但这不是理想情况下应该采用的方式。HashMap没有固定的时间访问权限,它只是因为内部的散列而看起来像这样。访问时间是
O(n)/bucketsize
,在大多数情况下可能是
1
,但它仍然是
O(n)/bucketsize
(这是线性的)。我将其描述为O(log(log(n)),与我观察到的非常匹配。c.f.TreeSet是O(log(n)),一百万个条目大约比10慢5倍。HashSet包含()在一百万个条目上,大约比10个条目慢1.5倍(忽略缓存行为),集合是否在缓存中会产生更大的差异。;)HashMap没有固定的时间访问,它只是因为内部的哈希而看起来像这样。访问时间是
O(n)/bucketsize
,在大多数情况下可能是
1
,但它仍然是
O(n)/bucketsize
(这是线性的)。我将其描述为O(log(log(n)),与我观察到的非常匹配。c.f.TreeSet是O(log(n)),一百万个条目大约比10慢5倍。HashSet包含()在一百万个条目上,速度大约比10慢1.5倍(ignor
Queue<Point> points = new ArrayBlockingQueue<Point>(1024);
for(int i=0;i<1000;i++)
  points.add(new Point(i,i));
Point missing = new Point(-1, -1);
int runs = 100 * 1000;
long start = System.nanoTime();
for(int i=0;i< runs;i++)
    points.contains(missing);
long time = System.nanoTime() - start;
System.out.printf("Average contains() took %.1f us%n", time/runs/1000.0);
Average contains() took 5.1 us