我相信有一个很好的理由,但有人能解释一下为什么java.util.Set接口缺少get(int Index),或任何类似的get()方法吗?

集合似乎很适合把东西放进去,但我找不到一种优雅的方法来从中检索单个项目。

如果我知道我想要的第一项,我可以使用set.iterator().next(),但否则,似乎我必须强制转换到一个数组来检索特定索引的项?

从集合中检索数据的适当方法是什么?(与使用迭代器不同)

我相信它被排除在API之外的事实意味着有一个很好的理由不这样做——有人能启发我吗?

编辑: 这里有一些非常棒的回答,还有一些说“更多的背景”。具体的场景是一个dbUnit测试,在这个测试中,我可以合理地断言从查询返回的集合只有1个项,并且我正在尝试访问该项。

然而,这个问题在没有场景的情况下更有效,因为它仍然更集中:

set和list的区别是什么?

感谢大家的精彩回答。


当前回答

你可以用new ArrayList<T>(set)。get(index)

其他回答

我能想到的在集合中使用数值索引的唯一原因是为了迭代。为此,请使用

for(A a : set) { 
   visit(a); 
}

The reason why the Set interface doesn't have a get index-type call or even something even more basic, such as first() or last(), is because it is an ambiguous operation, and therefore a potentially dangerous operation. If a method returns a Set, and you call, say first() method on it, what is the expected result, given that the a generic Set makes no guarantees on the ordering? The resultant object could very well vary between each call of the method, or it might not and lull you into a false sense of security, until the library you're using changes changes the implementation underneath and now you find that all your code breaks for no particular reason.

这里列出的关于变通办法的建议很好。如果需要索引访问,请使用列表。对泛型Set使用迭代器或toArray时要小心,因为a)不能保证顺序,b)不能保证顺序不会随着后续调用或不同的底层实现而改变。如果你需要介于两者之间的东西,SortedSet或LinkedHashSet就是你想要的。

// 我希望Set界面有一个get-random-元素。

因为集合没有顺序。有些实现可以(特别是那些实现java.util.SortedSet接口的实现),但这不是集合的一般属性。

如果您试图以这种方式使用集合,则应该考虑使用列表。

如果您不介意要排序的集合,那么您可能有兴趣看看索引树映射项目。

增强的TreeSet/TreeMap提供了通过索引访问元素或获取元素索引的功能。实现基于更新RB树中的节点权重。所以这里没有迭代,也没有列表备份。

根据Set集合的定义,Set中的元素是无序的。所以它们不能被索引访问。

但是为什么我们没有一个get(object)方法,不是通过提供索引作为参数,而是提供一个与我们正在寻找的对象相等的对象? 通过这种方式,我们可以访问Set中元素的数据,只需要知道equal方法使用的属性。