Java 是否有一种有效的方法来确定队列项目是否为;“之前”;另一个?

Java 是否有一种有效的方法来确定队列项目是否为;“之前”;另一个?,java,queue,Java,Queue,对于我的Java应用程序,我需要一些方法来确定item1是否在队列Q中的item2之前。当然,我可以使用迭代器开始遍历列表。然而,也许有另一种方法可以找到答案 对于我的特定应用程序,我不能使用LinkedList(它提供索引并使确定一个对象是否在另一个对象之前变得容易)。不,没有。根据定义,队列上的唯一操作是排队和退队,因此如果您的应用程序需要其他操作,那么队列的结构就不正确。LinkedList是一个非常基本的类,很难想象有什么可以替代它。除了ArrayList,它支持随机访问,并且可以更快地

对于我的Java应用程序,我需要一些方法来确定item1是否在队列Q中的item2之前。当然,我可以使用迭代器开始遍历列表。然而,也许有另一种方法可以找到答案


对于我的特定应用程序,我不能使用LinkedList(它提供索引并使确定一个对象是否在另一个对象之前变得容易)。

不,没有。根据定义,队列上的唯一操作是排队和退队,因此如果您的应用程序需要其他操作,那么队列的结构就不正确。

LinkedList是一个非常基本的类,很难想象有什么可以替代它。除了ArrayList,它支持随机访问,并且可以更快地进行索引访问。但是,ArrayList的效率不如queue。

一般来说,队列将提供一个“peek”操作,它可以让您在不删除队列的情况下查看队列顶部的内容,但其他任何内容都需要不同的数据结构。否则,您将从队列中弹出内容并将其放到另一个队列中,直到找到为止,此时您需要重新查询弹出的值。

如果您只需要确定item2是否已在队列中, 您可以使用java.util.LinkedHashMap来维护插入顺序,并可用作后进先出队列。

a是a,因此您可以始终将其元素复制到另一个允许您检索顺序的
集合,例如

List<YourType> copy = new ArrayList<YourType>(yourQueue);
if(copy.indexOf(obj1)<copy.indexOf(obj2)){
    // some code here
}

当然,您必须在访问迭代器之前同步队列,因此这也是非常低效的。

我建议使用可以引用查找表的优先级队列。这样,您就可以获得想要获得的元素的恒定性能,以及多项式插入成本。但是,如果您只是尝试进行比较,而不是查找最佳或最差优先级的项目,那么这可能是专门为您使用的。然而,持续的性能总是很好的。然后不必迭代数组,只需查找。

我将保留一个从队列对象到整数的单独哈希映射,以及您添加到队列中的对象总数的运行计数(因此,当插入对象X时,计数器表示对象X是插入的第n个对象)。每次向队列添加对象时,将其作为键添加到HashMap中;该值是计数器的当前值


当您需要询问两个对象中的哪一个是第一个时,请在HashMap中查找它们并比较序号。无论哪一个都有较低的值。

< P>如果快速知道顺序是一个大问题,那么考虑将一个“订单”字段添加到您的元素中,并重写您的队列实现以填充该字段。
我不会把链接索引作为解决方案。它是作为列表遍历实现的。

您可以使用队列以外的其他数据结构吗?我想使用队列,因为它效率高。请参阅okay,在这种情况下,使用List=Collections.synchronizedList(新LinkedList)可能更好;而不是ConcurrentLinkedQueue。如果您只需要队列的操作,并且不尝试将其用作链接列表,那么ConcurrentLinkedQueue可能会很快。如何将其用作后进先出队列?它没有队列所需的任何peek()、poll()等方法。我能想到的唯一方法是使用
map.entrySet().iterator().next()
,但这效率太低了!我不会用效率极低这个词。在大多数用例中,这很好。列表中有多少条目,需要多长时间执行一次操作?除非您已经测量到,
map.entrySet().iterator().next()
是代码中的一个问题,否则不要担心它。添加“order”或“index”字段需要更多空间,但速度要快得多。我认为取舍是可以的。。。
/**
 * Returns -1 if a occurs in the collection before b, 1 if b occurs before a
 * and 0 otherwise.
 */
public static <T> int comparePositionInCollection(final T a,
    final T b,
    final Collection<T> collection){

    // todo: check for a==null, b==null, a.equals(b)

    final Iterator<T> iterator = collection.iterator();
    boolean foundA = false;
    boolean foundB = false;
    int result = 0;
    while(iterator.hasNext()){
        final T t = iterator.next();
        if(a.equals(t)){
            if(foundB){
                result = 1;
                break;
            }
            foundA = true;
        } else if(b.equals(t)){
            if(foundA){
                result = -1;
                break;
            }
            foundB = true;
        }
    }
    return result;
}