简体   繁体   English

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

[英]To store unique element in a collection with natural order

While I was solving a Java test I came up with the following question: 在解决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

I have no idea what is the right case here? 我不知道这里合适的情况是什么? We can store the same element in any of these collections unless in a Set , but the Set doesn't provide the natural order. 我们可以在所有这些集合中存储相同的元素,除非在Set ,但是Set不提供自然顺序。 What's wrong? 怎么了?

TreeSet would give you ordering (either natural ordering by default of custom ordering via a Comparator). TreeSet会给您排序(默认情况下是自然排序,默认情况下是通过比较器的自定义排序)。

To be more general, SortedSet is the more general interface that offers uniqueness and ordering. 更笼统地说, SortedSet是更通用的接口,提供唯一性和顺序。

A Set that further provides a total ordering on its elements. 一个Set,进一步提供其元素的总体排序。 The elements are ordered using their natural ordering, or by a Comparator typically provided at sorted set creation time. 元素使用其自然顺序或通过通常在排序集创建时提供的Comparator进行排序。 The set's iterator will traverse the set in ascending element order. 集合的迭代器将以升序顺序遍历集合。 Several additional operations are provided to take advantage of the ordering. 提供了一些其他操作以利用订购的优势。

The correct answer for that test is Set Let's remember that it's asking for an interface that could provide that; 该测试的正确答案是Set请记住,它要求一个可以提供该功能的接口。 given the right implementation , the Set interface could provide it. 给定正确的实现Set接口可以提供它。

  • The Map interface doesn't make any guarantees around what order things are stored, as that's implementation specific. Map界面无法保证事物的存储顺序,因为这是特定于实现的。 However, if you use the right implementation (that is, TreeMap as spelled out by the docs), then you're guaranteed a natural ordering and no duplicate entries. 但是,如果使用正确的实现(即文档说明的TreeMap ),则可以保证顺序自然且没有重复的条目。

    However, there's no requirement about key-value pairs. 但是,对键值对没有要求。

  • The Set interface also doesn't make any guarantees around what order things are stored in, as that's implementation specific. Set接口也不能保证存储的顺序,因为这是特定于实现的。 But, like TreeMap , TreeSet is a set that can be used to store things in a natural order with no duplicates. 但是,与TreeMap一样, TreeSet是一个集合,可以用于以自然顺序存储事物,没有重复项。

    Here's how it'd look. 这是它的外观。

     Set<String> values = new TreeSet<>(); 
  • The List interface will definitely allow duplicates, which instantly rules it out. List接口肯定会允许重复,这会立即将其排除在外。

  • The Collection interface doesn't have anything directly implementing it, but it is the patriarch of the entire collections hierarchy. Collection接口没有直接实现它的任何东西,但是它是整个collection层次结构的先祖。 So, in theory, code like this is legal: 因此,从理论上讲,这样的代码是合法的:

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

    ...but you'd lose information about what kind of collection it actually was, so I'd discourage its usage. ...但是您会丢失有关它实际上是哪种类型的信息,因此我不鼓励使用它。

If by natural order, you mean order of insertion, then LinkedHashSet is your go to Set implementation. 如果按自然顺序表示插入顺序,那么LinkedHashSet是Set实现的入口

The correct answers are: SortedSet gives guarantees, regarding natural order of elements. 正确的答案是: SortedSet提供有关元素自然顺序的保证。 TreeSet is typical implementation TreeSet是典型的实现

Strictly speaking, when choosing from the above List is the only of the interfaces that has a defined order of iteration, however it does allow duplicates. 严格来说,从上面的List选择时,只有具有定义的迭代顺序的接口是唯一的,但是它确实允许重复。

Set and Map on the other hands, does not allow duplicates (of keys for Map ), but they also do not define the order of iteration, they are unordered by default, with HashSet / HashMap being the counter example. 另一方面, SetMap不允许重复( Map的键),但是它们也没有定义迭代的顺序,默认情况下它们是无序的,其中HashSet / HashMap是反示例。

Collection allows none. Collection不允许。

So, strictly speaking - none of the suggested interfaces provide the desired capability, However, as others suggested, there are specific implementations of the interfaces that do allow natural order of elements and no duplicates, mainly the SortedSet interface and its TreeSet implementation 因此,严格来说-所建议的接口都不提供所需的功能,但是,正如其他人所建议的那样,接口的特定实现确实允许元素的自然顺序且没有重复,主要是SortedSet接口及其TreeSet实现


To further elaborate why Set is not a good option, if you have a variable, let it be mySet , and you want it to be ordered, users are going to be surprised when you use the Set interface, imaigine the following code: 为了进一步说明为什么Set不是一个好的选择,如果您有一个变量,将其设为mySet ,并且希望对其进行排序,那么在使用Set接口时,用户会感到惊讶,请输入以下代码:

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

and users provide you a HashSet as argument - you are going to get a wrong behavior from your method, because Set does not guarantee ordering. 并且用户为您提供了HashSet作为参数-您将从方法中得到错误的行为,因为Set不能保证排序。 To avoid it you should have asked for an SortedSet rather than Set . 为了避免这种情况,您应该要求使用SortedSet而不是Set

I've come over this question yesterday on my interview test and need to comment on that: the question (assuming one of the listed A, B, C or D answers has to be correct) is plainly wrong. 我昨天在面试中遇到了这个问题,需要对此发表评论:这个问题(假设列出的A,B,C或D答案之一必须正确)显然是错误的。 There is no correct answer listed. 没有列出正确的答案。

Nothing in Set interface guarantees the order in which the elements are to be returned. Set接口中的任何内容都不能保证元素返回的顺序。 And there is no such thing, as Makoto would like it in his accepted answer , as right implementation that could theoretically do the job, because we are not asked for any implementation here, but whether interface provides the requested capability. 诚如Makoto在他接受的答案中所希望的那样,没有什么事情可以作为理论上可以完成工作的正确实现 ,因为在这里我们没有要求任何实现,而是接口是否提供了所要求的功能。

So, the test question with the answers provided is misguided. 因此,带有所提供答案的测试问题被误导了。

Referring a bit more to accepted answer , 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. Makoto认为,具体地说, List接口肯定会允许重复项,从而立即将其排除在外。 This argument may be defied by citation from List specification saying: 可以通过引用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 并非无法想象有人希望通过在用户尝试插入运行时异常时抛出运行时异常来实现禁止重复的列表,但我们希望这种用法很少见

so in my opinion, any of the answers given is equally wrong, or, as accepted answer wants it, equally correct, as we are free to write implementation of List (or Map, or Collection) behaving in any way we wish (in boundaries set by an interface specification), but interfaces and their specifications are here to guarantee some contract, and this question is really about them, not about possible implementations. 因此,我认为,给出的任何答案都同样是错误的,或者,正如公认的答案所希望的那样,同样是正确的,因为我们可以自由编写List(或Map或Collection)的实现,其行为是我们希望的(在边界内) (由接口规范设置),但是接口及其规范在这里是为了保证一定的约定,这个问题实际上是关于它们的,而不是关于可能的实现的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM