LinkedHashSet中的项目索引重复

时间:2015-08-08 12:45:08

标签: java indexing set linkedhashset

我正在为LinkedHashSet添加一些值并基于add()方法的输出,即true / false,我正在执行其他操作。

如果Set包含重复元素,则返回false,在这种情况下,我想知道Set中重复元素的索引,因为我需要在其他地方使用该索引。成为一个“联系”的人。收集必须有一些方法来获取索引,但我无法在Set / LinkedHashSet API中找到任何此类内容。

1 个答案:

答案 0 :(得分:2)

LinkedHashSet未明确编入索引本身。如果您需要索引,则对此类应用程序使用Set通常是错误抽象和/或糟糕编程的标志。 LinkedHashSet仅保证您可预测的迭代顺序,正确索引元素。在这种情况下,您应该使用List,因为这是为您提供索引保证的界面。但是,您可以使用几种方法推断索引,例如(不推荐,请注意):

a)在集合中使用索引迭代(例如使用for循环),寻找重复并在发现时断开;它是获得索引的O(n)复杂度,

Object o; // this is the object you want to add to collection
if ( !linkedHashSet.add(o) ) {
    int index = 0;
    for( Object obj : linkedHashSet ) {
        if ( obj == o ) // or obj.equals(o), depending on your code's semantics
            return index;
        index++;
    }
}

b)使用.toArray()并找到数组中的元素,例如由

Object o; // this is the object you want to add to collection
int index;
if ( !linkedHashSet.add(o) )
    index = Arrays.asList(linkedHashSet.toArray()).indexOf(o);

再次,O(n)获得指数的复杂性。

两者都会导致严重的运行时损失(第二种解决方案在效率方面明显更差,因为每次寻找索引时都会创建一个数组;创建一个镜像集合的并行数组会更好)。总而言之,我在你的例子中看到了一个破碎的抽象。你说

  

我需要在其他地方使用该索引

...如果那个真的这种情况,那么使用Set 99%的时间本身就是错误的。

另一方面,您可以使用Map(例如HashMap),其中包含[index,Object](或[Object,index],具体取决于具体用例)配对。它需要一些重构,但它是IMO的首选方法。它为大多数操作提供了与LinkedHashSet相同的复杂度顺序,但你得到的O(1)基本上是免费获取索引(Java的HashSet内部使用HashMap ,所以你不会因HashSet替换HashMap而失去任何记忆。

更好的方法是使用类显式处理整数映射 - 有关详细信息,请参阅HashMap and int as key; tl; dr - http://trove.starlight-systems.com/TIntObjectHashMap& TObjectIntHashMap,为您提供可能的最佳速度。