有没有一种方法可以创建一个保持插入顺序并且不允许在Java中重复的列表/集?
维护一个不允许重复但保持插入顺序并且还允许检索 Java 中最后插入的元素的列表的最有效方法是什么?
What is the most efficient way of maintaining a list that does not allow duplicates, but maintains insertion order and also allows the retrieval of the last inserted element in Java?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
尝试 LinkedHashSet,它会保持输入的顺序。
<罢工>
请注意,重新插入元素会更新其在输入顺序中的位置,因此您可以首先尝试检查该元素是否已包含在集合中。
编辑
:
您还可以尝试 Apache commons 集合类 ListOrderedSet 根据 JavaDoc(如果我没有再次读错任何内容:))将装饰一个集合以保持插入顺序并提供一个
get(index)
方法。因此,似乎您可以通过使用 new ListOrderedSet(new HashSet()) 来获得您想要的东西;
不幸的是,此类不提供通用参数,但它可能会帮助您入门。
编辑2:
这是一个项目,它似乎代表具有泛型的公共集合,即它有一个
ListOrderedSet
因此,您可以例如调用new ListOrderedSet(new HashSet());
Try LinkedHashSet, which keeps the order of input.
Note that re-inserting an element would update its position in the input order, thus you might first try and check whether the element is already contained in the set.
Edit:
You could also try the Apache commons collections class ListOrderedSet which according to the JavaDoc (if I didn't missread anything again :) ) would decorate a set in order to keep insertion order and provides a
get(index)
method.Thus, it seems you can get what you want by using
new ListOrderedSet(new HashSet())
;Unfortunately this class doesn't provide a generic parameter, but it might get you started.
Edit 2:
Here's a project that seems to represent commons collections with generics, i.e. it has a
ListOrderedSet<E>
and thus you could for example callnew ListOrderedSet<String>(new HashSet<String>());
我不认为 JDK 中有任何东西可以做到这一点。
但是, LinkedHashMap 用作 LinkedHashSet 的基础,它很接近:它维护映射中条目的循环双向链表。它只跟踪列表的头部而不是尾部,但因为列表是循环的,所以
header.before
是尾部(最近插入的元素)。因此,您可以在此基础上实现您需要的内容。 LinkedHashMap 并没有为扩展而设计,所以这有点尴尬。您可以将代码复制到您自己的类中并添加合适的
last()
方法(请注意此处的许可问题),或者您可以扩展现有类,并添加一个使用反射来获取的方法在私有header
和before
字段中。这会给你一张地图,而不是一套。但是, HashSet 已经是一个包装器,它使 Map 看起来像一个 Set。同样,它不是为一般扩展而设计的,但您可以编写一个子类,其构造函数调用超级构造函数,然后使用更多反射将超类的
map
值替换为新映射的实例。从那时起,班级应该完全按照您的意愿行事。顺便说一句,这里的图书馆课程都是由 Josh Bloch 和 Neal Gafter 编写的。这两个人是 Java 的两位巨人。然而其中的代码非常糟糕。永远不会遇见你的英雄。
I don't think there's anything in the JDK which does this.
However, LinkedHashMap, which is used as the basis for LinkedHashSet, comes close: it maintains a circular doubly-linked list of the entries in the map. It only tracks the head of the list not the tail, but because the list is circular,
header.before
is the tail (the most recently inserted element).You could therefore implement what you need on top of this. LinkedHashMap has not been designed for extension, so this is somewhat awkward. You could copy the code into your own class and add a suitable
last()
method (be aware of licensing issues here), or you could extend the existing class, and add a method which uses reflection to get at the privateheader
andbefore
fields.That would get you a Map, rather than a Set. However, HashSet is already a wrapper which makes a Map look like a Set. Again, it is not designed for general extension, but you could write a subclass whose constructor calls the super constructor, then uses more reflection to replace the superclass's value of
map
with an instance of your new map. From there on, the class should do exactly what you want.As an aside, the library classes here were all written by Josh Bloch and Neal Gafter. Those guys are two of the giants of Java. And yet the code in there is largely horrible. Never meet your heroes.
只需使用
TreeSet
。Just use a
TreeSet
.