如何获取Set的第n个元素

mar*_*gti 9 java collections set

更具体地说:如何获取LinkedHashSet的第n个元素(具有可预测的迭代顺序)?我想检索插入到其中的第n个元素Set(它尚未存在).

是否更好地使用List:

List<T> list = new ArrayList<T>(mySet);
T value = list.get(x); // x < mySet.size()
Run Code Online (Sandbox Code Playgroud)

toArray(T [] a)方法:

T [] array = mySet.toArray(new T[mySet.size()]);
T value = array[y]; // y < mySet.size()
Run Code Online (Sandbox Code Playgroud)

除了(可能是轻微的)性能差异之外,还有什么值得注意的?任何明显的赢家?

编辑1

注意:为什么我想要最后插入的元素并不重要,重要的是我想要它.LinkedHashSet是专门选择的,因为它"定义了迭代排序,这是元素插入集合(插入顺序)的顺序.请注意,如果将元素重新插入集合中,插入顺序不会受到影响."

编辑2

这个问题似乎已经演化成是否讨论任何 Set实现可以永远保留原始的广告订单.所以我在http://pastebin.com/KZJ3ETx9上提供了一些简单的测试代码来表明是的,LinkedHashSet确实保留了插入顺序(与其迭代顺序相同),就像它的Javadoc声称的那样.

编辑3

修改了问题的描述,以便每个人都不太专注于检索最后一个元素Set(我原本以为问题的标题就足够了 - 显然我错了).

Pat*_*han 6

此方法基于更新的要求返回第 n 个元素,而不仅仅是最后一个元素。如果源是例如带有标识符的 Set 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;
  }
Run Code Online (Sandbox Code Playgroud)


mar*_*gti 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

代码版本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;
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:经过一些细微的修改,上述方法可用于所有Iterables<T>.

这避免了确保 aSet和 aList保持同步的开销,也避免了List每次都必须创建一个新的(这比任何算法复杂性都更耗时)。

显然,我使用 aSet来确保唯一性,并且我宁愿避免冗长的解释来解释为什么我需要索引访问。