我正在为LinkedHashSet
添加一些值并基于add()
方法的输出,即true / false,我正在执行其他操作。
如果Set
包含重复元素,则返回false,在这种情况下,我想知道Set
中重复元素的索引,因为我需要在其他地方使用该索引。成为一个“联系”的人。收集必须有一些方法来获取索引,但我无法在Set
/ LinkedHashSet
API中找到任何此类内容。
答案 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
,为您提供可能的最佳速度。