在我解决Java测试时,我提出了以下问题:
您需要将元素存储在集合中,以保证不存在 存储重复项,并且可以自然地访问所有元素 订购。哪个界面提供了这种功能?
A. java.util.Map
B. java.util.Set
C. java.util.List
D. java.util.Collection
我不知道这里的正确案例是什么?我们可以在任何这些集合中存储相同的元素,除非在Set
中,但Set
不提供自然顺序。怎么了?
答案 0 :(得分:2)
TreeSet会为您提供排序(默认情况下通过比较器自定义排序)。
更一般地说,SortedSet是提供唯一性和排序的更通用的界面。
进一步提供其元素的总排序的集合。元素按照它们的自然顺序排序,或者通过通常在排序集创建时提供的比较器排序。 set的迭代器将按升序元素顺序遍历集合。提供了几个额外的操作以利用订购。
答案 1 :(得分:2)
该测试的正确答案是 Set
让我们记住它要求的界面可以提供该测试;如果正确实现,Set
接口可以提供它。
Map
界面并未对所存储的内容进行任何保证,因为该特定的实施方式。但是,如果您使用正确实施(即文档详细说明的TreeMap
),那么您将确保自然排序并且没有重复条目。
但是,对键值对没有要求。
Set
界面也不保证存储内容的顺序,具体是针对具体实现的。但是,与TreeMap
一样,TreeSet
是一个可用于以自然顺序存储事物且没有重复项的集合。
以下是它的外观。
Set<String> values = new TreeSet<>();
List
界面肯定会允许重复,这会立即排除它。
Collection
界面没有任何直接实现它,但它是整个集合层次结构的族长。因此,从理论上讲,这样的代码是合法的:
Collection<String> values = new TreeSet<>();
...但是你失去了关于它实际上是什么类型的收集的信息,所以我不鼓励它的使用。
答案 2 :(得分:1)
如果按自然顺序表示插入顺序,则 LinkedHashSet 是您转到Set实现。
正确答案是: SortedSet 提供有关元素自然顺序的保证。 TreeSet 是典型的实现
答案 3 :(得分:0)
严格地说,从上面选择List
时,只有具有已定义迭代次序的接口,但它确实允许重复。
Set
和Map
不允许重复(Map
的键),但它们也没有定义迭代的顺序,默认情况下它们是无序的,HashSet
/ HashMap
是反例。
Collection
不允许任何内容。
因此,严格来说 - 建议的接口都没有提供所需的功能,
但是,正如其他人所建议的那样,接口的特定实现确实允许元素的自然顺序而没有重复,主要是SortedSet
接口及其TreeSet
实现
为了进一步说明为什么Set
不是一个好的选择,如果你有一个变量,让它为mySet
,你想要它被订购,用户在你使用时会感到惊讶Set
界面,想象以下代码:
public int processMyDataStructure(Set set) {
//some calculation that assumes set is ordered
return result;
}
并且用户为您提供HashSet
作为参数 - 您将从您的方法中获得错误的行为,因为Set
不保证排序。为避免这种情况,您应该要求SortedSet
而不是Set
。
答案 4 :(得分:0)
我昨天在面试时遇到了这个问题,需要对此发表评论:问题(假设所列出的A,B,C或D答案之一必须正确)显然是错误的。 没有列出正确答案。
Set接口中的任何内容都不保证返回元素的顺序。并且没有这样的事情,因为Makoto希望在他的accepted answer中,因为 正确的实施 理论上可以完成这项工作,因为我们这里没有要求任何实现,但是 interface 是否提供了所请求的功能。
因此,提供答案的测试问题是错误的。
再多说一点accepted answer,还有一个原因是错误的。具体来说,Makoto认为, List接口肯定会允许重复,这会立即排除它。这个论点可能会被List规范的引用说明:
有人可能希望通过在用户尝试插入运行时异常时抛出运行时异常来实现禁止重复的列表并不是不可思议,但我们希望这种用法很少见
因此在我看来,给出的任何答案都是同样错误的,或者,正如accepted answer所希望的那样,同样正确,因为我们可以自由地编写任何行为的List(或Map或Collection)的实现我们希望的方式(在接口规范设置的边界内),但接口及其规范在这里保证某些合同,这个问题实际上是关于它们的,而不是关于可能的实现。