Java 使用哪种数据结构保持列表唯一,插入顺序保持不变

Java 使用哪种数据结构保持列表唯一,插入顺序保持不变,java,data-structures,collections,Java,Data Structures,Collections,我需要向列表中添加对象(使用list语义),同时保持列表中所有对象的唯一性。我认为LinkedHashSet可以,但“re-insert”子句打破了这一点: 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);

我需要向列表中添加对象(使用
list
语义),同时保持列表中所有对象的唯一性。我认为
LinkedHashSet
可以,但“re-insert”子句打破了这一点:

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);
LinkedHashSetlist=新建LinkedHashSet();
列表。添加(“a”);
列表。添加(“b”);
列表。添加(“c”);
列表。添加(“a”);
列表。添加(“a”);
System.out.println(列表);
上面的输出是:
[a,b,c]
,而不是我想要的
[b,c,a]


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

我认为没有现成的数据结构可以满足您的需要,因为它看起来有点奇怪。我建议您在LinkedHashSet周围创建一个包装器,当您尝试重新插入元素时,它会弹出该元素,然后再次插入它。

试试看

    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);

实际上,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;
}
/**
*使用构造空LinkedHashMap实例
*指定的初始容量、负载系数和订购模式。
*
*@param initialCapacity初始容量
*@param loadFactor荷载系数
*@param accessOrder订购模式-对于
*访问顺序,对于插入顺序为false
*如果初始容量为负,@将引发IllegalArgumentException
*或者负载系数是非正的
*/
公共LinkedHashMap(int初始容量,
浮动荷载系数,
布尔存取顺序){
超级(初始容量、负载系数);
this.accessOrder=accessOrder;
}
有一个额外的参数
accessOrder
。基于此,新添加的对象将移动到列表的末尾(
accessOrder-true
)或保留在旧位置(
accessOrder-false

为了创建具有这些特征的
集合
,您需要从
java.util.Collections
newSetFromMap(LinkedHashMap(initialCapacity,loadFactor,accessOrder))


请记住,
accessOrder
属性负责与给定元素的所有交互-如果您在
HashMap
上调用
get
,它也会重新排序(这无论如何都不会影响您,因为
Set
接口不会在包装的
HashMap
上公开
get
方法,只是说)。

预期的行为是什么?这不允许重复。为什么您希望输出是
[b,c,a]
?LinkedHashSet维护插入顺序,因此输出。我认为op需要最后一次插入顺序(如果重新插入密钥,其位置应更改为新位置)。@GangnamStyleOverflower TreeSet不维护插入顺序。@m0skit0预期行为在我的问题中有详细说明(列表语义+集合唯一性)。这是一个好主意,但值得一提的是get也会改变顺序。@assylias是的,但是
Set
没有get(),所以它可以工作。这是一个非常聪明的主意。@MartinWickman你完全正确-我的评论毫无意义。反正我给了+1。“创建说唱歌手”?:)@m0skit0 AHAHAHA这只是让打字变得如此有趣的打字错误之一谢谢:)
/**
 * 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;
}