用于保持列表唯一且插入顺序完整的数据结构

时间:2013-01-23 09:42:07

标签: java data-structures collections

我需要将对象添加到列表中(使用List语义),同时保持列表中的所有对象都是唯一的。我认为LinkedHashSet会这样做,但“重新插入”条款打破了这个:

LinkedHashSet<String>list = new LinkedHashSet<String>();
list.add("a");
list.add("b");
list.add("c");
list.add("a");
list.add("a");
System.out.println (list);

上面的输出是[a, b, c],而不是我想要的[b, c, a]

Java中是否有处理这种情况的数据结构?

3 个答案:

答案 0 :(得分:8)

    Set<String> set = Collections.newSetFromMap(new LinkedHashMap<String, Boolean>(16, 0.75f, true));
    set.add("a");
    set.add("b");
    set.add("c");
    set.add("a");
    set.add("a");
    System.out.println(set);

输出

[b, c, a]

答案 1 :(得分:3)

我不认为有一个开箱即用的数据结构可以做你想要的,因为它看起来有点奇怪。我建议你在LinkedHashSet周围创建一个包装器,当你尝试重新插入它时弹出元素,然后重新插入它。

答案 2 :(得分:2)

实际上,JDK库提供了开箱即用的数据结构。如果你看一下这个LinkedHashMap构造函数:

/**
 * Constructs an empty <tt>LinkedHashMap</tt> instance with the
 * specified initial capacity, load factor and ordering mode.
 *
 * @param  initialCapacity the initial capacity
 * @param  loadFactor      the load factor
 * @param  accessOrder     the ordering mode - <tt>true</tt> for
 *         access-order, <tt>false</tt> for insertion-order
 * @throws IllegalArgumentException if the initial capacity is negative
 *         or the load factor is nonpositive
 */
public LinkedHashMap(int initialCapacity,
                     float loadFactor,
                     boolean accessOrder) {
    super(initialCapacity, loadFactor);
    this.accessOrder = accessOrder;
}

还有一个额外的参数accessOrder。基于此,新添加的对象将移动到列表末尾(accessOrder - true)或保留在旧位置(accessOrder - false)。

要创建具有这些特征的Set,您需要使用java.util.Collections中的此工厂方法:newSetFromMap(LinkedHashMap(initialCapacity, loadFactor, accessOrder))

请注意,accessOrder属性负责所有与给定元素的互动 - 如果您在get上调用HashMap,它会进行重新排序同样(这不应该影响你,因为Set接口不会在包裹的get上公开HashMap方法,只是说。)