更具体地说:如何获取LinkedHashSet的第n个元素(具有可预测的迭代顺序)?我想检索插入此Set
的
使用List
:
List<T> list = new ArrayList<T>(mySet);
T value = list.get(x); // x < mySet.size()
或toArray(T [] a)
方法:
T [] array = mySet.toArray(new T[mySet.size()]);
T value = array[y]; // y < mySet.size()
除了(可能是轻微的)性能差异外,还有什么值得注意的?任何明显的赢家?
NB: 为什么我想要最后插入的元素并不重要,重要的是我想要它。 LinkedHashSet是专门选择的,因为它“定义了迭代排序,这是元素插入集合(插入顺序)的顺序。请注意,如果元素重新插入集合中,插入顺序不会受到影响。“
这个问题似乎已经转变为讨论任何 Set
实现是否永远保留原始广告订单。所以我在http://pastebin.com/KZJ3ETx9放了一些简单的测试代码来表明是的,LinkedHashSet确实保留了插入顺序(与迭代顺序相同),就像它的Javadoc声称的那样。
修改了问题的描述,以便每个人都不太专注于检索Set
的最后一个元素(我原本以为问题的标题就足够了 - 显然我错了)。
答案 0 :(得分:4)
此方法基于更新的要求返回第n个元素,而不仅仅是最后一个元素。如果来源是例如标识为mySet
的集合,可以通过nthElement(mySet, mySet.size()-1)
选择最后一个元素。
如果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;
}
。
{{1}}
答案 1 :(得分:2)
如果你想检索最后一个元素,我会使用LinkedHashSet的迭代器:
Iterator<T> it = linkedHashSet.iterator();
T value = null;
while (it.hasNext()) {
value = it.next();
}
循环执行值将引用最后一个元素。
答案 2 :(得分:2)
所以我决定采用@Juvanis的答案略有不同。
获取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;
}
}
代码的第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:稍作修改,上述方法可用于所有Iterables<T>
。
这避免了确保Set
和List
保持同步的开销,并且还避免了每次都必须创建新的List
(这会更费时比任何数量的算法复杂度。)
显然我使用Set
来确保唯一性,而我宁愿避免冗长解释为什么我需要索引访问。
答案 3 :(得分:1)
你可以使用以下解决方案, 这里我在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;
}
}
答案 4 :(得分:0)
Set是无序的,因此插入的最后一个元素的信息将丢失。你不能这样插入最后一个元素。所以不要首先使用Set,或者,如果你真的想跟踪最后一个元素,请创建一个包含这样的类
class mySetAndLast extends Set{
T last;
Set<T> mySet;
}
现在的问题是插入的最后一个元素&#39;。想象一下你的装置是空的
-> insert x -> ok, x is the last inserted
-> insert y (y!=x) -> ok: y is the last inserted
-> insert x -> ?
现在是最后插入的x还是y? x没有插入,因为y是插入的最后一个元素,x已经是该集合的元素,另一方面,x是用户的观点,是最后插入的..
答案 5 :(得分:0)
为了您自己的内部目的,您可以&#34; hack&#34;来自任何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.
}
这个例子很慢(添加时为O(n))但是,正如您实现它的那样,您可以根据您的规范使用更智能的contains()
代码返回到它。