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

Java:如何从一个集合中获取n个元素,java,set,java-8,Java,Set,Java 8,我试图找到从x开始的集合中获取n个元素的最优雅的方法。我得出的结论是使用流: Set<T> s; Set<T> subS = s.stream().skip(x).limit(n).collect(Collectors.toSet()); Set; Set subS=s.stream().skip(x).limit(n).collect(Collectors.toSet()); 这是最好的方法吗?有什么缺点吗 您可以在集合上迭代并收集前n个元素: int n = 0;

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

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

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

您可以在集合上迭代并收集前n个元素:

int n = 0;
Iterator<T> iter = set.iterator();
while (n < 8  && iter.hasNext()) {
 T t = iter.next();
 list.add(t);
 n++;
}
Iterables.limit(Iterables.skip(s, x), n);
int n=0;
迭代器iter=set.Iterator();
而(n<8&&iter.hasNext()){
T=iter.next();
列表。添加(t);
n++;
}
好处是它应该比更通用的解决方案更快


缺点是它比您建议的更详细。

一个集合(以其原始方式)不打算具有有序元素,因此您不能从元素x开始。SortedSet可能是您想要使用的“set”

我会先把它转换成一个列表,比如

    new ArrayList(s).subList(<index of x>, <index of x + n>);
新数组列表。子列表(,);

但这可能会对性能产生非常坏的影响。在这种情况下,必须存储ArrayList以检索下一个子列表,因为没有显式顺序,而隐式顺序可能会在下次调用
新ArrayList
时更改。

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

首先,一个集合不是用来获取它的特定元素的- 您应该使用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++;
}
intc=0;
int n=50//要获取的元素数
迭代器iter=set.Iterator();

虽然(c使用番石榴,
Iterables.limit(s,20)
与Steve Kuo的答案类似,但也跳过了前x元素:

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

您的代码不起作用

列表的顺序将是
集合的顺序,如果在
数组列表的创建时有任何或任意顺序,则该顺序将是固定的,之后不会更改

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

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

也就是说,处理由位置号给出的
集合的一部分是很不寻常的。

这个问题属于哪个。另外,你需要更精确地说明你的
集合是什么,因为标准一号只使用一种泛型类型。对codereview来说肯定更好。我觉得很好。是的,我不知道该在哪里发布。感觉很好假设元素0是
“foo”
,元素1是
“bar”
。将
“baz”
添加到集合中,现在元素0可能是
“bar”
(因为内部哈希表已展开并重新格式化)。或者,重用迭代器并依赖于
ConcurrentModificationException
也不能保证总是有效。您还可以使用
for
for(int n=0;n
那就更好了。谢谢。我很感谢你在执行自己的编辑之前接受我的建议;)(我会从接受中得到两个代表)问题是“这是最好的方式吗?有什么缺点吗?”。你能解释一下你的答案如何比OP已有的更好吗?非常好而且有效的答案。下面是“选择接口”将是SortedSet?我认为SortedSet不是必需的。这里的主要问题是保留订单(无论是否排序)。实际上,这主要取决于实现。排序集实际上是一个很好的替代方案,可以解决多次运行问题。如果这是您的要求。但是,如果我不希望对我的集进行排序,而是保持元素的插入顺序,会发生什么情况?如果您希望插入顺序排序,您需要
LinkedHashSet
这将导致与潜在性能较差的流相同的输出。我还没有研究java8流,但这些新类似乎提供了类似迭代器的功能,并结合了更强大的语法和一些聚合函数。ArrayList变体似乎会减少OP代码的更改,因为将集合更改为ortedSet是一项艰苦的工作(个人经验)。流变体的实现更加优雅(如果它不是为了解决“根本问题”)。这不会跳过前x元素。
Set<T> subSet=new HashSet<>(sub);