Java 如何获取集合的第 n 个元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24464279/
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
How to get nth element of a Set
提问by markvgti
More specifically: how to get the nth element of a LinkedHashSet(which has a predictable iteration order)? I want to retrieve the nth element inserted into this Set
(which wasn't already present).
更具体地说:如何获取LinkedHashSet的第 n 个元素(具有可预测的迭代顺序)?我想检索插入其中的第 n 个元素Set
(尚未存在)。
Is it better to use a List
:
使用List
:更好吗?
List<T> list = new ArrayList<T>(mySet);
T value = list.get(x); // x < mySet.size()
or the toArray(T [] a)
method:
或toArray(T [] a)
方法:
T [] array = mySet.toArray(new T[mySet.size()]);
T value = array[y]; // y < mySet.size()
Other than the (likely slight) performance differences, anything to watch out for? Any clear winner?
除了(可能是轻微的)性能差异之外,还有什么需要注意的?有明确的赢家吗?
Edit 1
编辑 1
NB:It doesn't matter whyI want the last-inserted element, all that matters is that I want it. LinkedHashSet was specifically chosen because it "defines the iteration ordering, which is the order in which elements were inserted into the set (insertion-order). Note that insertion order is not affected if an element is re-inserted into the set."
注意:我为什么想要最后插入的元素并不重要,重要的是我想要它。选择 LinkedHashSet 是因为它“定义了迭代顺序,即元素插入到集合中的顺序(插入顺序)。请注意,如果将元素重新插入到集合中,插入顺序不会受到影响。”
Edit 2
编辑 2
This question seems to have devolved into a discussion of whether anySet
implementation can everpreserve original insertion order. So I put up some simple test code at http://pastebin.com/KZJ3ETx9to show that yes, LinkedHashSet does indeed preserve insertion order (the same as its iteration order) as its Javadoc claims.
这个问题似乎已经演化成是否讨论任何Set
实现可以永远保留原始的广告订单。所以我在http://pastebin.com/KZJ3ETx9上放了一些简单的测试代码来证明是的,LinkedHashSet 确实像它的 Javadoc 声称的那样保留了插入顺序(与其迭代顺序相同)。
Edit 3
编辑 3
Modified the description of the problem so that everybody isn't too focused on retrieving the last element of the Set
(I originally thought that the title of the question would be enough of a hint — obviously I was wrong).
修改了问题的描述,让大家不会太专注于检索最后一个元素Set
(我原本以为问题的标题已经足够提示了——显然我错了)。
采纳答案by markvgti
So I decided to go with a slight variation of the answer by @Juvanis.
所以我决定对@Juvanis 的答案略有不同。
To get at the nth element in a LinkedHashSet:
要获取 LinkedHashSet 中的第 n 个元素:
Iterator<T> itr = mySet.iterator();
int nth = y;
T value = null;
for(int i = 0; itr.hasNext(); i++) {
value = itr.next();
if (i == nth) {
break;
}
}
Version 2 of the code:
代码的第 2 版:
public class SetUtil {
@Nullable
public static <T> T nthElement(Set<T> set, int n) {
if (null != set && n >= 0 && n < set.size()) {
int count = 0;
for (T element : set) {
if (n == count)
return element;
count++;
}
}
return null;
}
}
NB:with some slight modifications the method above can be used for all Iterables<T>
.
注意:稍加修改,上述方法可用于所有Iterables<T>
.
This avoids the overhead of ensuring that a Set
and a List
stay in sync, and also avoids having to create a new List
every time (which will be more time-consuming than any amount of algorithmic complexity).
这避免了确保 aSet
和 aList
保持同步的开销,也避免了List
每次都必须创建一个新的(这将比任何数量的算法复杂性都更耗时)。
Obviously I am using a Set
to ensure uniqueness and I'd rather avoid a lengthy explanation as to why I need indexed access.
显然我使用 aSet
来确保唯一性,我宁愿避免冗长的解释为什么我需要索引访问。
回答by Juvanis
I'd use the iterator of the LinkedHashSet if you want to retrieve the last element:
如果你想检索最后一个元素,我会使用 LinkedHashSet 的迭代器:
Iterator<T> it = linkedHashSet.iterator();
T value = null;
while (it.hasNext()) {
value = it.next();
}
After the loop execution value will be referring to the last element.
循环执行后的值将引用最后一个元素。
回答by HelpVampire666
Set is unordered so the information on the last element inserted is lost. You cannot as such get the last element inserted. So don't use Set in the first place, or, if you really want to keep track of the last element, create a class containing that like this
Set 是无序的,因此最后插入的元素的信息会丢失。您不能因此插入最后一个元素。所以首先不要使用 Set ,或者,如果您真的想跟踪最后一个元素,请创建一个包含这样的类
class mySetAndLast extends Set{
T last;
Set<T> mySet;
}
now the question is what is the 'last element inserted'. Imagine your set was empty
现在的问题是“最后插入的元素”是什么。想象你的集合是空的
-> insert x -> ok, x is the last inserted
-> insert y (y!=x) -> ok: y is the last inserted
-> insert x -> ?
is now x or y the last inserted? x does not get inserted because y was the last element inserted and x already is an element of the set, on the other hand x from the user's point of view was the last inserted..
现在是 x 还是 y 最后插入?x 没有被插入,因为 y 是最后插入的元素,而 x 已经是集合的一个元素,另一方面,从用户的角度来看,x 是最后插入的。
回答by Patricia Shanahan
This method is based on the updated requirement to return the nth element, rather than just the last element. If the source is e.g. a Set with identifier mySet
, the last element can be selected by nthElement(mySet, mySet.size()-1)
.
此方法基于更新的要求返回第 n 个元素,而不仅仅是最后一个元素。如果源是例如带有标识符的 Set mySet
,则可以通过 选择最后一个元素nthElement(mySet, mySet.size()-1)
。
If n
is small compared to the size of the Set
, this method may be faster than e.g. converting to an ArrayList
.
如果n
与 的大小相比较小Set
,则此方法可能比例如转换为ArrayList
.
/**
* Return an element selected by position in iteration order.
* @param data The source from which an element is to be selected
* @param n The index of the required element. If it is not in the
* range of elements of the iterable, the method returns null.
* @return The selected element.
*/
public static final <T> T nthElement(Iterable<T> data, int n){
int index = 0;
for(T element : data){
if(index == n){
return element;
}
index++;
}
return null;
}
回答by Matthieu
For your own, internal purpose, you could "hack" your own Set
from any List
implementation:
为了您自己的内部目的,您可以Set
从任何List
实现中“破解”您自己的实现:
public class ListSet<E> extends ArrayList<E> implements Set<E> {
@Override
public boolean add(E item) {
return contains(item) ? false : super.add(item);
}
// ... and same for add(int, E), addAll(...), etc.
}
That example is slow (O(n) for an add) but, as you are the one implementing it, you can go back to it with smarter code for contains()
based on your specifications.
该示例很慢(添加的 O(n))但是,由于您是实现它的人,因此您可以contains()
根据您的规范使用更智能的代码返回它。
回答by Hardik Patel
You can go with below solution, here i have added object of ModelClass in HashSet.
您可以使用以下解决方案,这里我在 HashSet 中添加了 ModelClass 对象。
ModelClass m1 = null;
int nth=scanner.nextInt();
for(int index=0;index<hashset1.size();index++){
m1 = (ModelClass) itr.next();
if(nth == index) {
System.out.println(m1);
break;
}
}