是否有一个保存Set的插入顺序也实现了List?

yeg*_*256 82 java collections

我正在尝试在Java中找到java.util.Listjava.util.Set同时实现它.我希望这个类只允许唯一的元素(as Set)并保留它们的顺序(比如List).JDK 6中是否存在?

重要的是List<T>#add(int, T)我可以插入特定位置.

Jon*_*eet 204

TreeSet按元素顺序排序; LinkedHashSet保留插入订单.希望其中一个就是你所追求的.

你已经指定你希望能够在任意位置插入,我怀疑你必须自己编写 - 只需创建一个包含a HashSet<T>和a的类ArrayList<T>; 添加项目时,在将其添加到列表之前检查它是否在集合中.

  • @ yegor256:如果你事先说过......编辑会很有用. (9认同)

Mec*_*kov 30

LinkedHashSet就是答案.

迭代排序和唯一性.

http://download.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html


Pet*_*rey 11

你的意思是LinkedHashSet吗?这保留了输入顺序,但不允许重复.

恕我直言,这是一个不寻常的要求,但你可以写一个没有重复的列表.

class SetList<T> extends ArrayList<T> {
    @Override
    public boolean add(T t) {
        return !super.contains(t) && super.add(t);
    }

    @Override
    public void add(int index, T element) {
        if (!super.contains(element)) super.add(index, element);
    }

    @Override
    public boolean addAll(Collection<? extends T> c) {
        boolean added = false;
        for (T t : c)
            added |= add(t);
        return added;
    }

    @Override
    public boolean addAll(int index, Collection<? extends T> c) {
        boolean added = false;
        for (T t : c)
            if (!super.contains(t)) {
                super.add(index++, t);
                added = true;
            }
        return added;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • http://stackoverflow.com/a/8185105/253468看起来更好,因为它没有`O(n)`的插入复杂性,在双重存储和`O(log(n))`插入之间需要权衡取舍操作。 (2认同)

Tag*_*eev 7

你无法实现ListSet不违反合同一次.例如,参见Set.hashCode合同:

集合的哈希码被定义为集合中元素的哈希码的总和,其中空元素的哈希码被定义为零.

另一方面,这是合同List.hashCode:

列表的哈希码被定义为以下计算的结果:

int hashCode = 1;
for (E e : list)
    hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
Run Code Online (Sandbox Code Playgroud)

所以不可能实现单一类,以保证两个合同都得到满足.equals实施同样的问题.