有效地从集合中提取前k个元素

时间:2014-09-02 15:16:19

标签: java algorithm

问题

我正在编写一个简单的Java程序,其中我有TreeSet,其中包含 Comparable 元素(这是我自己写的一个类)。在特定时刻,我需要从 元素。

我做了什么

目前,我发现了两个不同的解决方案:

  1. 使用我写的简单方法;它复制了初始TreeSet;
  2. 中的第一个 k 元素
  3. 使用 Google Guava greatestOf方法。
  4. 对于第二个选项,您需要以这种方式调用方法: Ordering.natural().greatestOf(mySet, 80))

    但我认为使用这种调用是没用的,因为元素已经被排序了。我错了吗?

    问题

    我想问一下这是一个正确的,同时又是一种有效的方法来获得Collection派生类,它包含{{1}的第一个 k 元素}?

    其他信息

    Java版本:> = 7

3 个答案:

答案 0 :(得分:2)

你可以使用Guava的Iterables#limit

ImmutableList.copyOf(Iterables.limit(yourSet, 7))

http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Iterables.html#limit(java.lang.Iterable,int)

答案 1 :(得分:1)

我建议您使用TreeSet<YourComparableClass>集合,它似乎是您正在寻找的解决方案。

TreeSet可以返回一个迭代器,你可以简单地迭代K次,通过存储迭代器返回给你的对象:元素将按顺序返回给你。

此外,TreeSet会始终对元素进行排序:在任何时候,当您添加或删除元素时,都会插入和删除它们,以便结构保持有序。

这是一个可能的例子:

public static ArrayList<YourComparableClass> getFirstK(TreeSet<YourComparableClass> set, int k) {
    Iterator<YourComparableClass> iterator = set.iterator();
    ArrayList<YourComparableClass> result = new ArrayList<>(k); //to store first K items
    for (int i=0;i<k;i++) result.add(iterator.next()); //iterator returns items in order
    //you should also check iterator.hasNext(); if you are not sure to have always a K<set.size()
    return result;
}

答案 2 :(得分:0)

descendingIterator() method of java.util.TreeSet会产生从最大到最小的元素,因此您可以多次执行它,将元素插入到集合中。运行时间为O(log n + k),其中k是返回的元素数,这肯定足够快。

另一方面,如果您正在使用HashSet,那么元素实际上已排序,因此您需要使用线性时间选择方法你表示。