以自然顺序将唯一元素存储在集合中

To store unique element in a collection with natural order

当我解决 Java 测试时,我想到了以下问题:

You need to store elements in a collection that guarantees that no duplicates are stored and all elements can be accessed in natural order. Which interface provides that capability?

A. java.util.Map
B. java.util.Set
C. java.util.List
D. java.util.Collection

我不知道这里的正确情况是什么?我们可以在任何这些集合中存储相同的元素,除非在 Set 中,但 Set 不提供自然顺序。怎么了?

TreeSet 会给你排序(默认情况下的自然排序或通过比较器自定义排序)。

更一般地说,SortedSet 是提供唯一性和排序的更一般的接口。

A Set that further provides a total ordering on its elements. The elements are ordered using their natural ordering, or by a Comparator typically provided at sorted set creation time. The set's iterator will traverse the set in ascending element order. Several additional operations are provided to take advantage of the ordering.

如果按照自然顺序,您指的是插入顺序,那么 LinkedHashSet 是您的 Set 实现。

正确答案是: SortedSet 保证了元素的自然顺序。 TreeSet 是典型的实现

严格来说,从以上选择时,List 是唯一具有已定义迭代顺序的接口,但它确实允许重复。

另一方面,

SetMap 不允许重复(Map 的键),但它们也没有定义迭代顺序,它们是无序的默认情况下,HashSet/HashMap 是反例。

Collection 允许 none.

所以,严格来说 - none 的建议接口提供了所需的功能, 然而,正如其他人所建议的那样,有一些特定的接口实现允许元素的自然顺序并且没有重复,主要是 SortedSet interface and its TreeSet 实现


为了进一步说明为什么 Set 不是一个好的选择,如果你有一个变量,让它成为 mySet,并且你希望它被排序,当你使用Set接口,想象一下下面的代码:

public int processMyDataStructure(Set set) {
   //some calculation that assumes set is ordered
   return result;
}

并且用户为您提供了一个 HashSet 作为参数 - 您将从您的方法中获得错误的行为,因为 Set 不能保证排序。为避免这种情况,您应该要求 SortedSet 而不是 Set.

该测试的正确答案是 Set 让我们记住它要求的是可以提供该功能的接口;鉴于 正确的实现 Set 接口可以提供它。

  • Map 接口不保证事物的存储顺序,因为这是特定于实现的。但是,如果您使用 right 实现(即文档中拼写的 TreeMap),那么您可以保证自然排序并且没有重复条目。

    但是,对于键值对没有要求。

  • Set 接口也不保证事物的存储顺序,因为这是特定于实现的。但是,与 TreeMap 一样,TreeSet 是一个集合,可用于以自然顺序存储事物,不重复。

    这是它的样子。

    Set<String> values = new TreeSet<>();
    
  • List接口肯定会允许重复,直接排除

  • Collection接口没有任何直接实现它,但它是整个集合层次结构的元老。所以,理论上,这样的代码是合法的:

    Collection<String> values = new TreeSet<>();
    

    ...但是您会丢失有关它实际上是哪种集合的信息,所以我不鼓励使用它。

我昨天在面试时遇到了这个问题,需要对此发表评论:这个问题(假设列出的 A、B、C 或 D 答案之一必须是正确的)显然是错误的。 没有列出正确答案。

Set interface guarantees the order in which the elements are to be returned. And there is no such thing, as Makoto would like it in his 中没有任何内容,因为 正确的实施 理论上可以完成这项工作,因为我们没有被要求任何此处实现,但 接口 是否提供请求的功能。

所以,提供答案的试题是错误的。

更多参考 , there is one more reason for it to be wrong. Specifically, Makoto argues, that The List interface will definitely allow duplicates, which instantly rules it out. This argument may be defied by citation from List 规范说:

It is not inconceivable that someone might wish to implement a list that prohibits duplicates, by throwing runtime exceptions when the user attempts to insert them, but we expect this usage to be rare

所以在我看来,给出的任何答案都同样错误,或者,正如 所希望的那样,同样正确,因为我们可以自由编写 List(或 Map 或 Collection)的实现以我们希望的任何方式(在接口规范设置的边界内),但是接口和它们的规范在这里是为了 保证 一些契约,这个问题实际上是关于它们的,而不是关于可能的实现。