java 如何在java中从Iterable创建集合?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7850979/
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
How to create collection from Iterable in java?
提问by Artyom Chernetsov
For example, I have set of geometrical figures:
例如,我有一组几何图形:
Set<Figure> figures;
There are two types of Figure: Square and Circle.
图形有两种类型:方形和圆形。
I want to get set of squares using google collections:
我想使用谷歌集合获得一组正方形:
Iterables.filter(figures,squarePredicate);
But filter method return Iterable... How can I create Set from Iterable? (without using loop on Iterable)
但是过滤器方法返回 Iterable... 如何从 Iterable 创建 Set?(在 Iterable 上不使用循环)
回答by Sean Patrick Floyd
I think you need to rethink your requirements. You need a set of squares. Why?
我认为您需要重新考虑您的要求。你需要一组正方形。为什么?
A set gives you uniqueness and iteration, nothing more. You have uniqueness in your Iterable, because the source is a set, and you can iterate over the items in an Iterable. So why would you need the set?
一套给你唯一性和迭代,仅此而已。您的 Iterable 具有唯一性,因为源是一个集合,您可以迭代 Iterable 中的项目。那你为什么需要这个集合?
There are only two possible reasons: either you are working with an API that needs a Set (or Collection) parameter, or you need to somehow display the Set's size.
只有两个可能的原因:要么您正在使用需要 Set(或 Collection)参数的 API,要么您需要以某种方式显示 Set 的大小。
In these cases, use Sets.newHashSet(iterable)
to create a Set (on one hand of course that requires a full iteration, on the other hand: you will need a full iteration at one point anyway when you are iterating over the values, so why not do it now?). Otherwise, just use the Iterable and forget about a Set.
在这些情况下,用于Sets.newHashSet(iterable)
创建一个 Set(一方面当然需要完整迭代,另一方面:当您迭代值时,无论如何您都需要在某一点进行完整迭代,所以为什么不现在做呢? ?)。否则,只需使用 Iterable 而忘记 Set。
回答by ColinD
If you have a Set
, you can use Sets.filter
rather than Iterables.filter
and get a Set
result. That Set
is a live view, like the result of Iterables.filter
, but it has Set
properties such as a fast contains
method.
如果您有Set
,则可以使用Sets.filter
而不是Iterables.filter
并获得Set
结果。这Set
是一个实时视图,就像 的结果一样Iterables.filter
,但它具有Set
诸如快速contains
方法之类的属性。
To create a copycontaining only the elements that match the predicate, you can use ImmutableSet.copyOf
or Sets.newHashSet
as others have suggested.
要创建仅包含与谓词匹配的元素的副本,您可以使用ImmutableSet.copyOf
或Sets.newHashSet
按照其他人的建议。
回答by Etienne Neveu
Guava's Iterables.filter()
deliberately returns an Iterable "view". There are two benefits to this approach:
番石榴Iterables.filter()
故意返回一个可迭代的“视图”。这种方法有两个好处:
- you only iterate over the elements when you really need to (e.g. you can chain Iterables.filter() and Iterables.transform() calls, and iterate only once at the end).
- you can create the appropriate collection from the view, using something like
ImmutableSet.copyOf(Iterables.filter(..., ...))
,Sets.newHashSet(Iterables.filter(..., ...))
, orLists.newArrayList(Iterables.filter(..., ...))
. Iterables.filter() lets you choose the precise collection needed, instead of returning an arbitrary one.
- 您只在真正需要时迭代元素(例如,您可以链接 Iterables.filter() 和 Iterables.transform() 调用,并且最后只迭代一次)。
- 您可以从视图中创建适当的集合,使用类似
ImmutableSet.copyOf(Iterables.filter(..., ...))
,Sets.newHashSet(Iterables.filter(..., ...))
, 或Lists.newArrayList(Iterables.filter(..., ...))
。Iterables.filter() 允许您选择所需的精确集合,而不是返回任意集合。
I also noticed that you seem to use Iterables.filter(Iterable unfiltered, Predicate predicate)with a predicate to filter instances of a specific type. You might also be interested in the Iterables.filter(Iterable unfiltered, Class type)overload, that filters all instances of the given type, and returns an Iterable with the more specific generic type. This lets you avoid awkward casts.
我还注意到您似乎将Iterables.filter(Iterable unfiltered, Predicate predicate)与谓词一起使用来过滤特定类型的实例。您可能还对Iterables.filter(Iterable unfiltered, Class type)重载感兴趣,它过滤给定类型的所有实例,并返回具有更具体泛型类型的 Iterable。这可以让您避免尴尬的演员表。
回答by Dave Newton
Use something like Sets.newHashSet(Iterable)
(or whatever you need it to be).
使用类似的东西Sets.newHashSet(Iterable)
(或任何你需要的东西)。
回答by kgautron
Maybe try CollectionUtils.filter()
from apache collection utils instead? You can use it on a Set, or use the resulting collection in the Set constructor.
也许尝试CollectionUtils.filter()
从 apache collection utils 代替?您可以在 Set 上使用它,或者在 Set 构造函数中使用生成的集合。
回答by Jeffrey Bosboom
You can filter a set and collect into another set with Java 8 streams:
您可以使用 Java 8 流过滤一个集合并收集到另一个集合中:
Set<Number> integers = numbers.stream()
.filter(x -> x instanceof Integer)
.collect(Collectors.toSet());
The returned set is a copy, not a live view.
返回的集合是副本,而不是实时视图。
Note that unlike, e.g., Guava's FluentIterable.filter, the resulting set is a Set<Integer>
because Java doesn't know you've filtered out all the non-integers. If you need a Set<Integer>
, you have to map after filtering.
请注意,与 Guava 的FluentIterable.filter 等不同,结果集是 a,Set<Integer>
因为 Java 不知道您已过滤掉所有非整数。如果需要Set<Integer>
,则必须在过滤后映射。
Set<Integer> integers = numbers.stream()
.filter(x -> x instanceof Integer)
.map(x -> (Integer)x)
.collect(Collectors.toSet());
(You could combine the filter and map into a flatMap, but that would introduce a temporary stream object per integer, and isn't any more concise.)
(您可以将过滤器和映射组合到一个 flatMap 中,但这会为每个整数引入一个临时流对象,并且不再简洁。)