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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31124014/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 18:08:50  来源:igfitidea点击:

Java: How to get n elements from a set

javasetjava-8

提问by Diaa

I was trying to find the most elegant way to get the n elements from a set starting from x. What I concluded was using streams:

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

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

Is this the best way to do it this way? Are there any drawbacks?

这是这样做的最佳方式吗?有什么缺点吗?

回答by JamesB

Similar to Steve Kuo's answer but also skipping the first x elements:

类似于 Steve Kuo 的回答,但也跳过了第一个 x 元素:

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

Guava Iterables

番石榴迭代

回答by Steve Kuo

Use Guava, Iterables.limit(s, 20).

使用番石榴,Iterables.limit(s, 20)

回答by Holger

Your code doesn't work.

你的代码不起作用。

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

What is Set<T,C>? A Setcontains elements of a given type so what are the twotype parameters supposed to mean?

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

Further, if you have a Set<T>, you don't have a defined order. “the n elements from a set starting from x” makes no sense in the context of a Set. There are some specialized Setimplementations which have an order, e.g. are sorted or do retain insertion order, but since your code doesn't declare such prerequisite but seems to be supposed to work on an arbitrary Set, it must be considered broken.

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

If you want to process a fraction of the Setaccording to an order, you have to freeze the order first:

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

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

The list will have an order which will be the order of the Set, if there is any, or an arbitrary order, fixed at the creation time of the ArrayList, which will not change afterwards.

该列表将具有一个顺序,该顺序将是 的顺序(Set如果有)或任意顺序,在 的创建时固定,ArrayList此后不会更改。

Then, extracting a fragment of it, is easy:

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

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

You may also convert it back to a Set, if you wish:

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

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

That said, it's rather unusual to process a part of a Setgiven by positional numbers.

也就是说,Set通过位置数字处理给定的一部分是相当不寻常的。

回答by Ivan Mushketyk

You can just iterate over set and collect first n elements:

您可以遍历 set 并收集前 n 个元素:

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

The benefit is that it should be faster than more generic solutions.

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

The drawback is that it's more verbose than the one that you suggested.

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

回答by Johannes

A set - in its original manner - is not intended to have ordered elements, so you can not start from element x. SortedSet may be the "set" you want to use.

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

I'd convert it to a List first, like

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

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

but it may have a very bad impact on performance. In this case the ArrayList would have to be stored to retrive the next subList because there is no explicit order, and the implicit order may change the next time new ArrayList(s)is called.

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

回答by barunsthakur

The use of Streamis fine. The one drawback I can see is not all implementation of Setis ordered e.g. HashSetis not ordered but LinkedHashSetis. SO you might get different resulting set on different run.

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

回答by Coder55

First, a set is not made for getting specific elements of it - you should use a sortedSet or a ArrayList instead.

首先,集合不是用于获取它的特定元素——您应该使用 sortedSet 或 ArrayList 代替。

But if you have to get the elements of the set, you can use the following code to iterate over the set:

但是如果非要获取集合的元素,可以使用下面的代码遍历集合:

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++;
}