可以在不使用终端操作的情况下知道流的大小

时间:2016-06-27 01:43:50

标签: java-8 java-stream

我有3个接口

name='ckmeans._ckmeans_wrapper'

我需要实施public interface IGhOrg { int getId(); String getLogin(); String getName(); String getLocation(); Stream<IGhRepo> getRepos(); } public interface IGhRepo { int getId(); int getSize(); int getWatchersCount(); String getLanguage(); Stream<IGhUser> getContributors(); } public interface IGhUser { int getId(); String getLogin(); String getName(); String getCompany(); Stream<IGhOrg> getOrgs(); }

此方法返回与大多数贡献者(getContributors())

的IGhRepo

我试过这个

Optional<IGhRepo> highestContributors(Stream<IGhOrg> organizations)

但它给了我

  

java.lang.IllegalStateException:stream已经被操作或关闭

我知道count()是Stream中的终端操作,但我无法解决这个问题,请帮忙!

感谢

3 个答案:

答案 0 :(得分:3)

您没有指定此内容,但看起来某些或可能所有返回Stream<...>值的接口方法在每次调用时都不会返回新流。

从API的角度来看,这对我来说似乎有问题,因为它意味着每个流,并且对象功能的一大部分最多可以使用一次。

您可以通过确保每个对象的流只在方法中使用一次来解决您遇到的特定问题,如下所示:

Optional<IGhRepo> highestContributors(Stream<IGhOrg> organizations) {
  return organizations
      .flatMap(IGhOrg::getRepos)
      .distinct()
      .map(repo -> new AbstractMap.SimpleEntry<>(repo, repo.getContributors().count()))
      .max(Map.Entry.comparingByValue())
      .map(Map.Entry::getKey);
}

不幸的是,如果你想(例如)打印一个贡献者列表,你似乎会陷入困境,因为从getContributors()为返回的IGhRepo返回的流已经被消耗掉了。

每次调用流返回方法时,您可能需要考虑让实现对象返回一个新流。

答案 1 :(得分:3)

  

可以在不使用终端操作的情况下知道流的大小

不,不是,因为流可以是无限的,也可以按需生成输出。它们没有必要由集合支持。

  

但它给了我

java.lang.IllegalStateException: stream has already been operated upon or closed

因为您在每次方法调用时返回相同的流实例。你应该返回一个新的流。

  

我知道count()是Stream中的终端操作但是我无法解决这个问题,请帮忙!

恕我直言,你在这里滥用了这些流。性能和简单性更好,您返回一些Collection<XXX>而不是Stream<XXX>

答案 2 :(得分:1)

否。

无法知道java中流的大小。

正如java 8 stream docs

中所述
  

没有存储空间。流不是存储元素的数据结构;   相反,它传递来自数据结构等来源的元素,   数组,生成器函数或I / O通道,通过管道   计算操作。