如何在java中创建Iterable的集合?

Art*_*sov 6 java collections guava

例如,我有一组几何图形:

Set<Figure> figures;
Run Code Online (Sandbox Code Playgroud)

图有两种类型:Square和Circle.

我想使用google集合获取一组正方形:

Iterables.filter(figures,squarePredicate);
Run Code Online (Sandbox Code Playgroud)

但是filter方法返回Iterable ...如何从Iterable创建Set?(不使用Iterable循环)

Sea*_*oyd 15

我想你需要重新考虑你的要求.你需要一组正方形.为什么?

集合为您提供唯一性和迭代,仅此而已.您在Iterable中具有唯一性,因为源是一个集合,您可以迭代Iterable中的项目.那你为什么需要这套呢?

只有两个可能的原因:要么使用需要Set(或Collection)参数的API,要么以某种方式显示Set的大小.

在这些情况下,Sets.newHashSet(iterable)用来创建一个Set(另一方面,当然需要完整迭代的一方面:当你迭代这些值时,无论如何你都需要一个完整的迭代,所以为什么现在不去做?).否则,只需使用Iterable并忘记Set.


Col*_*inD 7

如果你有Set,你可以使用Sets.filter而不是Iterables.filter得到一个Set结果.这Set是一个实时视图,就像结果一样Iterables.filter,但它具有Set诸如快速contains方法之类的属性.

要创建仅包含与谓词匹配的元素的副本,您可以使用ImmutableSet.copyOfSets.newHashSet像其他人所建议的那样使用.


Eti*_*veu 5

Guava Iterables.filter()故意返回一个Iterable"视图".这种方法有两个好处:

  • 您只需在需要时迭代元素(例如,您可以链接Iterables.filter()和Iterables.transform()调用,并且最后只迭代一次).
  • 您可以从视图中创建适当的收集,使用类似的ImmutableSet.copyOf(Iterables.filter(..., ...)),Sets.newHashSet(Iterables.filter(..., ...))Lists.newArrayList(Iterables.filter(..., ...)).Iterables.filter()允许您选择所需的精确集合,而不是返回任意集合.

我还注意到你似乎使用Iterables.filter(Iterable unfiltered,Predicate谓词)和谓词来过滤特定类型的实例.您可能还对Iterables.filter(Iterable unfiltered,Class type)重载感兴趣,它会过滤给定类型的所有实例,并返回具有更具体泛型类型的Iterable.这可以让你避免尴尬的演员阵容.