linkedHashSet 中重复项的索引
Duplicate item's index in linkedHashSet
我正在向 LinkedHashSet
添加一些值,并基于 add()
方法的输出,即 true/false,我正在执行其他操作。
如果 Set
包含重复元素,则 returns 为 false,在这种情况下,我想知道 Set
中重复元素的索引,因为我需要使用该索引别的地方。作为一个 'linked' 集合,必须有一些方法来获取索引,但我在 Set
/LinkedHashSet
API.
中找不到任何这样的东西
LinkedHashSet
未明确索引 本身 。如果您需要索引,对此类应用程序使用 Set
通常是错误抽象 and/or 糟糕编程的标志。 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)。
两者都会导致严重的运行时损失(第二种解决方案在效率方面显然更差,因为它会在您每次查找索引时创建一个数组;创建一个镜像集合的并行数组会更好)。总而言之,我在你的例子中看到了一个破碎的抽象。你说
I need to use that index somewhere else
...如果确实是 情况,使用 Set
本身 99% 的时间都是错误的。
另一方面,您可以使用 Map
(例如 HashMap
),其中包含 [index,Object]
(或 [Object,index]
,具体取决于具体用途案例)对在里面。它需要一些重构,但 IMO 是执行此操作的首选方法。对于大多数操作,它会为您提供与 LinkedHashSet
相同的复杂度顺序,但您基本上免费获得索引的时间为 O(1)(Java 的 HashSet
使用 HashMap
内部无论如何,所以你不会失去任何内存替换 HashSet
与 HashMap
).
更好的方法是使用 class 显式 处理整数映射 - 参见 HashMap and int as key for more information; tl;dr - http://trove.starlight-systems.com/ 有 TIntObjectHashMap
和 TObjectIntHashMap
,为您提供可能的此类操作的最佳速度。
我正在向 LinkedHashSet
添加一些值,并基于 add()
方法的输出,即 true/false,我正在执行其他操作。
如果 Set
包含重复元素,则 returns 为 false,在这种情况下,我想知道 Set
中重复元素的索引,因为我需要使用该索引别的地方。作为一个 'linked' 集合,必须有一些方法来获取索引,但我在 Set
/LinkedHashSet
API.
LinkedHashSet
未明确索引 本身 。如果您需要索引,对此类应用程序使用 Set
通常是错误抽象 and/or 糟糕编程的标志。 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)。
两者都会导致严重的运行时损失(第二种解决方案在效率方面显然更差,因为它会在您每次查找索引时创建一个数组;创建一个镜像集合的并行数组会更好)。总而言之,我在你的例子中看到了一个破碎的抽象。你说
I need to use that index somewhere else
...如果确实是 情况,使用 Set
本身 99% 的时间都是错误的。
另一方面,您可以使用 Map
(例如 HashMap
),其中包含 [index,Object]
(或 [Object,index]
,具体取决于具体用途案例)对在里面。它需要一些重构,但 IMO 是执行此操作的首选方法。对于大多数操作,它会为您提供与 LinkedHashSet
相同的复杂度顺序,但您基本上免费获得索引的时间为 O(1)(Java 的 HashSet
使用 HashMap
内部无论如何,所以你不会失去任何内存替换 HashSet
与 HashMap
).
更好的方法是使用 class 显式 处理整数映射 - 参见 HashMap and int as key for more information; tl;dr - http://trove.starlight-systems.com/ 有 TIntObjectHashMap
和 TObjectIntHashMap
,为您提供可能的此类操作的最佳速度。