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