有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

linkedHashSet中的java重复项索引

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

如果Set包含重复元素,则返回false,在本例中,我想知道Set中重复元素的索引,因为我需要在其他地方使用该索引。作为一个“链接”集合,必须有某种方法来获取索引,但我在Set/LinkedHashSetAPI中找不到任何这样的东西


共 (1) 个答案

  1. # 1 楼答案

    LinkedHashSet本身没有显式索引。如果你需要一个索引,在这样的应用程序中使用Set通常是错误的抽象和/或糟糕的编程的标志LinkedHashSet只保证可预测的迭代顺序,而不是元素的正确索引。在这种情况下,应该使用^{,因为这是提供索引保证的接口。但是,您可以使用两种方法推断索引,例如(不推荐,请注意):

    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%的时间是错误的

    另一方面,您可以使用MapHashMap例如),其中包含[index,Object](或[Object,index],具体取决于具体的用例)对。这需要一些重构,但我更喜欢这样做。对于大多数操作来说,它的复杂性顺序与LinkedHashSet相同,但对于基本上免费获取索引,您会得到O(1)(Java的HashSet在内部使用HashMap,所以用HashMap替换HashSet不会损失任何内存)

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