我正在寻找一个像Queue一样的数据结构,这样我就可以获得先入先出的行为,但理想情况下,我也能够在常规时间内查看该队列中是否存在元素使用HashMap,而不是使用LinkedList获得的线性时间。
我认为LinkedHashMap可能会完成这项工作,但是虽然我可以创建一个迭代器并且只需要删除迭代的第一个元素来生成一种poll()方法,但我想知道是否有更好的方法方式。
非常感谢提前
答案 0 :(得分:3)
我不知道是否有什么东西,但您可以轻松创建一个由Queue
和HashSet
组成的复合对象。所有修改操作都需要同时在两个集合上进行,以使它们保持同步。然后,您可以使用set for lookup,这应该非常快。
答案 1 :(得分:2)
通常,当您需要两个集合的行为时,您需要维护两个集合。一个简单的方法是拥有一个Queue和一个HashSet,当你从队列中删除时,总是对这两个进行添加并从HashMap中删除。
另一种方法是使用LinkedHashSet。这保留了添加的订单元素,您可以每次删除第一个/最旧的元素。
第三种选择是仅使用队列。虽然您可能喜欢O(1)查找时间,但您可能会发现只需搜索每个元素,它就足以满足您的要求。这可能比您预期的要快得多。即1000个元素应小于10微秒。
编辑:我同意,如果您不知道长度,最好使用两个系列。
然而,为了向您展示蛮力搜索也可以很快。要寻找的最慢的对象是不存在的对象。 (因为它必须比较每个元素)
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
您可能需要针对您的数据类型对此进行测试,因为等于()的时间和队列的大小可能会有所不同,但您可能会惊讶于您在10微秒内可以做的事情,而且可能足够快。