为什么 java.util.Set 没有 get(int index)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/769731/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why doesn't java.util.Set have get(int index)?
提问by Marty Pitt
I'm sure there's a good reason, but could someone please explain why the java.util.Set
interface lacks get(int Index)
, or any similar get()
method?
我确定有一个很好的理由,但有人可以解释为什么java.util.Set
接口缺少get(int Index)
,或任何类似的get()
方法?
It seems that sets are great for putting things into, but I can't find an elegant way of retrieving a single item from it.
似乎集合非常适合放入东西,但我找不到一种优雅的方式从中检索单个项目。
If I know I want the first item, I can use set.iterator().next()
, but otherwise it seems I have to cast to an Array to retrieve an item at a specific index?
如果我知道我想要第一个项目,我可以使用set.iterator().next()
,但否则似乎我必须转换为一个 Array 以检索特定索引处的项目?
What are the appropriate ways of retrieving data from a set? (other than using an iterator)
从集合中检索数据的适当方法是什么?(除了使用迭代器)
I'm sure the fact that it's excluded from the API means there's a good reason for not doing this -- could someone please enlighten me?
我确信它被排除在 API 之外的事实意味着有一个很好的理由不这样做——有人可以启发我吗?
EDIT:Some extremely great answers here, and a few saying "more context". The specific scenario was a dbUnit test, where I could reasonably assert that the returned set from a query had only 1 item, and I was trying to access that item.
编辑:这里有一些非常好的答案,还有一些说“更多上下文”。特定场景是 dbUnit 测试,我可以合理地断言查询返回的集合只有 1 个项目,并且我试图访问该项目。
However, the question is more valid without the scenario, as it remains more focussed:
然而,这个问题在没有场景的情况下更有效,因为它仍然更加集中:
What's the difference between set and list.
set 和 list 有什么区别。
Thanks to all for the fantastic answers below.
感谢下面所有精彩的回答。
采纳答案by Michael Myers
Because sets have no ordering. Some implementations do (particularly those implementing the java.util.SortedSet
interface), but that is not a general property of sets.
因为集合没有顺序。一些实现可以(特别是那些实现java.util.SortedSet
接口的实现),但这不是集合的一般属性。
If you're trying to use sets this way, you should consider using a list instead.
如果您尝试以这种方式使用集合,则应考虑改用列表。
回答by jsight
That is because Set only guarantees uniqueness, but says nothing about the optimal access or usage patterns. Ie, a Set can be a List or a Map, each of which have very different retrieval characteristics.
那是因为 Set 只保证唯一性,而没有说明最佳访问或使用模式。即,一个集合可以是一个列表或一个映射,每个都有非常不同的检索特征。
回答by Jonik
Just adding one point that was not mentioned in mmyers' answer.
只是添加一点在mmyers 的回答中没有提到。
If I know I want the first item, I can use set.iterator().next(), but otherwise it seems I have to cast to an Array to retrieve an item at a specific index?
What are the appropriate ways of retrieving data from a set? (other than using an iterator)
如果我知道我想要第一个项目,我可以使用 set.iterator().next(),但否则我似乎必须转换为一个数组来检索特定索引处的项目?
从集合中检索数据的适当方法是什么?(除了使用迭代器)
You should also familiarise yourself with the SortedSet
interface (whose most common implementation is TreeSet
).
您还应该熟悉SortedSet
接口(其最常见的实现是TreeSet
)。
A SortedSet is a Set (i.e. elements are unique) that is kept ordered by the natural orderingof the elements or using some Comparator
. You can easily access the first and last items using first()
and last()
methods. A SortedSet
comes in handy every once in a while, when you need to keep your collection both duplicate-free and ordered in a certain way.
SortedSet 是一个 Set(即元素是唯一的),它通过元素的自然顺序或使用 some来保持有序Comparator
。您可以使用first()
和last()
方法轻松访问第一个和最后一个项目。ASortedSet
每隔一段时间就会派上用场,当您需要保持您的收藏无重复并以某种方式排序时。
Edit: If you need a Set whose elements are kept in insertion-order (much like a List), take a look at LinkedHashSet
.
编辑:如果您需要一个元素按插入顺序保存的 Set(很像 List),请查看LinkedHashSet
.
回答by Hugo
The only reason I can think of for using a numerical index in a set would be for iteration. For that, use
我能想到的在集合中使用数字索引的唯一原因是迭代。为此,使用
for(A a : set) {
visit(a);
}
回答by skiphoppy
I'm not sure if anybody has spelled it out exactly this way, but you need to understand the following:
我不确定是否有人完全这样拼写过,但您需要了解以下内容:
There is no "first" element in a set.
集合中没有“第一个”元素。
Because, as others have said, sets have no ordering. A set is a mathematical concept that specifically does not include ordering.
因为,正如其他人所说,集合没有顺序。集合是一个数学概念,特别不包括排序。
Of course, your computer can't really keep a list of stuff that's not ordered in memory. It has to have some ordering. Internally it's an array or a linked list or something. But you don't really know what it is, and it doesn't really have a first element; the element that comes out "first" comes out that way by chance, and might not be first next time. Even if you took steps to "guarantee" a particular first element, it's still coming out by chance, because you just happened to get it right for one particular implementation of a Set; a different implementation might not work that way with what you did. And, in fact, you may not know the implementation you're using as well as you think you do.
当然,您的计算机无法真正保留未在内存中排序的内容列表。它必须有一些顺序。在内部,它是一个数组或链表或其他东西。但是你并不真正知道它是什么,它也没有真正的第一个元素;“第一个”出现的元素是偶然出现的,下次可能不是第一个。即使您采取措施来“保证”某个特定的第一个元素,它仍然是偶然出现的,因为您恰好在 Set 的一个特定实现中得到了正确的结果;不同的实现可能不适用于您所做的工作。而且,事实上,您可能并不像您认为的那样了解您正在使用的实现。
People run into this ALL. THE. TIME. with RDBMS systems and don't understand. An RDBMS query returns a set of records. This is the same type of set from mathematics: an unordered collection of items, only in this case the items are records. An RDBMS query result has no guaranteed order at all unless you use the ORDER BY clause, but all the time people assume it does and then trip themselves up some day when the shape of their data or code changes slightly and triggers the query optimizer to work a different way and suddenly the results don't come out in the order they expect. These are typically the people who didn't pay attention in database class (or when reading the documentation or tutorials) when it was explained to them, up front, that query results do not have a guaranteed ordering.
人们遇到了这一切。这。时间。用 RDBMS 系统,不明白。RDBMS 查询返回一组记录。这与数学中的集合类型相同:项目的无序集合,仅在这种情况下项目是记录。除非您使用 ORDER BY 子句,否则 RDBMS 查询结果根本没有保证的顺序,但人们总是假设它确实如此,然后有一天当他们的数据或代码的形状略有变化并触发查询优化器工作时,他们自己就会绊倒一种不同的方式,突然结果并没有按照他们期望的顺序出现。这些通常是那些在数据库课程中(或在阅读文档或教程时)没有注意的人,当事先向他们解释查询结果没有保证的顺序时。
回答by waxwing
This kind of leads to the question when you should use a set and when you should use a list. Usually, the advice goes:
这导致了何时应该使用集合以及何时应该使用列表的问题。通常,建议如下:
- If you need ordered data, use a List
- If you need unique data, use a Set
- If you need both, use either: a SortedSet (for data ordered by comparator) or an OrderedSet/UniqueList (for data ordered by insertion). Unfortunately the Java API does not yet have OrderedSet/UniqueList.
- 如果您需要有序数据,请使用列表
- 如果您需要唯一数据,请使用 Set
- 如果两者都需要,请使用:SortedSet(用于按比较器排序的数据)或 OrderedSet/UniqueList(用于按插入排序的数据)。不幸的是,Java API 还没有 OrderedSet/UniqueList。
A fourth case that appears often is that you need neither. In this case you see some programmers go with lists and some with sets. Personally I find it very harmful to see set as a list without ordering - because it is really a whole other beast. Unless you need stuff like set uniqueness or set equality, always favor lists.
经常出现的第四种情况是您两者都不需要。在这种情况下,您会看到一些程序员使用列表,而一些程序员使用集合。就我个人而言,我认为将 set 视为一个没有排序的列表是非常有害的——因为它真的是一个完全不同的野兽。除非您需要设置唯一性或设置相等性之类的东西,否则请始终使用列表。
回答by Andreas Petersson
some data structures are missing from the standard java collections.
标准 java 集合中缺少一些数据结构。
Bag (like set but can contain elements multiple times)
Bag(类似于 set 但可以多次包含元素)
UniqueList (ordered list, can contain each element only once)
UniqueList(有序列表,每个元素只能包含一次)
seems you would need a uniquelist in this case
在这种情况下,您似乎需要一个 uniquelist
if you need flexible data structures, you might be interested in Google Collections
如果您需要灵活的数据结构,您可能会对Google Collections感兴趣
回答by walls
That's true, element in Set are not ordered, by definition of the Set Collection. So they can't be access by an index.
确实如此,根据 Set 集合的定义,Set 中的元素没有排序。所以它们不能被索引访问。
But why don't we have a get(object) method, not by providing the index as parameter, but an object that is equal to the one we are looking for? By this way, we can access the data of the element inside the Set, just by knowing its attributes used by the equal method.
但是为什么我们没有 get(object) 方法,不是通过提供索引作为参数,而是提供一个与我们正在寻找的对象相等的对象?通过这种方式,我们可以访问Set内部元素的数据,只需知道equal方法使用的属性。
回答by Sorin Postelnicu
Actually this is a recurring question when writing JavaEE applications which use Object-Relational Mapping (for example with Hibernate); and from all the people who replied here, Andreas Petersson is the only one who understood the real issue and offered the correct answer to it: Java is missing a UniqueList! (or you can also call it OrderedSet, or IndexedSet).
实际上,在编写使用对象关系映射(例如使用 Hibernate)的 JavaEE 应用程序时,这是一个反复出现的问题;在所有在这里回复的人中,Andreas Petersson 是唯一了解真正问题并提供正确答案的人:Java 缺少一个 UniqueList!(或者您也可以将其称为 OrderedSet 或 IndexedSet)。
Maxwing mentioned this use-case (in which you need ordered AND unique data) and he suggested the SortedSet, but this is not what Marty Pitt really needed.
Maxwing 提到了这个用例(其中您需要有序且唯一的数据)并且他建议使用 SortedSet,但这并不是 Marty Pitt 真正需要的。
This "IndexedSet" is NOT the same as a SortedSet - in a SortedSet the elements are sorted by using a Comparator (or using their "natural" ordering).
此“IndexedSet”与 SortedSet 不同 - 在 SortedSet 中,元素通过使用比较器(或使用它们的“自然”排序)进行排序。
But instead it is closer to a LinkedHashSet (which others also suggested), or even more so to an (also inexistent) "ArrayListSet", because it guarantees that the elements are returned in the same order as they were inserted.
但相反,它更接近于 LinkedHashSet(其他人也建议),或者更接近于(同样不存在的)“ArrayListSet”,因为它保证元素的返回顺序与它们插入的顺序相同。
But the LinkedHashSet is an implementation, not an interface! What is needed is an IndexedSet (or ListSet, or OrderedSet, or UniqueList) interface! This will allow the programmer to specify that he needs a collection of elements that have a specific order and without duplicates, and then instantiate it with any implementation (for example an implementation provided by Hibernate).
但是 LinkedHashSet 是一个实现,而不是一个接口!需要的是一个IndexedSet(或ListSet,或OrderedSet,或UniqueList)接口!这将允许程序员指定他需要具有特定顺序且没有重复的元素集合,然后使用任何实现(例如 Hibernate 提供的实现)实例化它。
Since JDK is open-source, maybe this interface will be finally included in Java 7...
由于JDK是开源的,也许这个接口最终会被包含在Java 7中......
回答by lala
To get element in a Set, i use to following one:
要获取 Set 中的元素,我使用以下方法:
public T getElement(Set<T> set, T element) {
T result = null;
if (set instanceof TreeSet<?>) {
T floor = ((TreeSet<T>) set).floor(element);
if (floor != null && floor.equals(element))
result = floor;
} else {
boolean found = false;
for (Iterator<T> it = set.iterator(); !found && it.hasNext();) {
if (true) {
T current = it.next();
if (current.equals(element)) {
result = current;
found = true;
}
}
}
}
return result;
}