Java:如何从集合中获取n个元素

时间:2015-06-29 19:31:54

标签: java set java-8

我试图找到从x开始从集合中获取n个元素的最优雅方式。我的结论是使用流:

Set<T> s;
Set<T> subS = s.stream().skip(x).limit(n).collect(Collectors.toSet());

这是这样做的最好方法吗?有什么缺点吗?

7 个答案:

答案 0 :(得分:11)

类似于Steve Kuo的答案,但也跳过了前x个元素:

Iterables.limit(Iterables.skip(s, x), n);

Guava Iterables

答案 1 :(得分:8)

使用Guava,Iterables.limit(s, 20)

答案 2 :(得分:5)

您的代码不起作用。

Set<T,C> s;
Set<T,C> subS = s.stream().skip(x).limit(n).collect(Collectors.toSet());

什么是Set<T,C>Set包含给定类型的元素,那么两个类型参数应该是什么意思?

此外,如果您有Set<T>,则表示您没有已定义的订单。 “从x开始的集合中的n个元素”在Set的上下文中没有意义。有一些专门的Set实现有一个订单,例如排序或保留插入顺序,但由于您的代码没有声明这样的先决条件,但似乎应该在任意Set上工作,因此必须将其视为已损坏。

如果您想根据订单处理Set的一小部分,您必须先冻结订单:

Set<T> s;
List<T> frozenOrder=new ArrayList<>(s);

如果在Set的创建时间修复了任何订单或任意订单,则列表将有一个订单ArrayList,之后不会改变

然后,提取它的片段很容易:

List<T> sub=frozenOrder.subList(x, Math.min(s.size(), x+n));

如果您愿意,也可以将其转换回Set

Set<T> subSet=new HashSet<>(sub);

也就是说,处理由位置数给出的Set的一部分是相当不寻常的。

答案 3 :(得分:1)

一套 - 以其原始方式 - 不打算有序元素,因此你不能从元素x开始。 SortedSet可能是&#34; set&#34;你想用。

我首先将其转换为List,例如

    new ArrayList(s).subList(<index of x>, <index of x + n>);

但它可能会对性能产生非常不利的影响。在这种情况下,必须存储ArrayList以检索下一个subList,因为没有显式顺序,并且下次调用new ArrayList(s)时隐式顺序可能会更改。

答案 4 :(得分:1)

使用Stream很好。我可以看到的一个缺点并非所有Set的实现都是有序的,例如HashSet未订购,LinkedHashSet。因此,您可能会在不同的运行中得到不同的结果集。

答案 5 :(得分:1)

首先,不是为了获取它的特定元素而设置的 - 你应该使用sortedSet或ArrayList。

但是如果必须获取集合的元素,则可以使用以下代码 迭代集合:

int c = 0;
int n = 50; //Number of elements to get
Iterator<T> iter = set.iterator();
while (c<n  && iter.hasNext()) {
   T t = iter.next();
   list.add(t);
   c++;
}

答案 6 :(得分:0)

你可以迭代集合并收集前n个元素:

int n = 0;
Iterator<T> iter = set.iterator();
while (n < 8  && iter.hasNext()) {
 T t = iter.next();
 list.add(t);
 n++;
}

好处是它应该比更通用的解决方案更快。

缺点是它比你建议的更冗长。