尝试使用LinkedHashSet,它可以保持输入的顺序。
请注意,重新插入元素会更新其在输入顺序中的位置,因此您可能首先要检查元素是否已包含在集合中。
编辑:
您还可以尝试使用Apache commons collections类ListOrderedSet。如果我没有再次错读JavaDoc,它会按顺序装饰一个集合以保持插入顺序,并提供一个get(index)
方法。
因此,似乎您可以通过使用new ListOrderedSet(new HashSet())
来获得想要的结果;
不幸的是,这个类没有提供泛型参数,但它可能能帮助您入门。
编辑2:
这里有一个项目,它似乎使用泛型表示commons collections,即它有一个ListOrderedSet<E>
,因此您可以例如调用new ListOrderedSet<String>(new HashSet<String>());
List
且不允许重复项的类。在这种情况下,您将不得不自己实现它(可能通过将List
实现与Set
实现结合起来)。 - Joachim SauerLinkedHashSet::add
方法。 - Basil Bourque我认为JDK中没有任何东西可以做到这一点。
然而,LinkedHashMap作为LinkedHashSet的基础,接近实现了这个功能:它维护了一个循环双向链表来存储映射中的条目。它只跟踪列表的头部而不是尾部,但由于列表是循环的,header.before
就是尾部(最近插入的元素)。
因此,您可以在此基础上实现您需要的内容。LinkedHashMap并未设计用于扩展,因此这有些棘手。您可以将代码复制到自己的类中并添加一个合适的last()
方法(请注意许可问题),或者您可以扩展现有类,并添加一个使用反射获取私有header
和before
字段的方法。
这将会得到一个 Map,而不是 Set。然而,HashSet 已经是一个包装器,使得 Map 看起来像一个 Set。同样,它并不是为了一般的扩展而设计的,但你可以编写一个子类,其构造函数调用超类的构造函数,然后使用更多的反射来替换超类的 map
值为你的新 map 的实例。从那时起,该类应该完全符合你的要求。
顺便说一下,这里的库类都是由 Josh Bloch 和 Neal Gafter 编写的。这些人是 Java 的巨人之一。然而,那里的代码大部分都很糟糕。永远不要见你的英雄。
只需使用{{link1:TreeSet
}}。
List
是有序的,而不是排序的)。 - Joachim Sauer