Java-8 – you can know the size of the stream without using terminal operations
I have three interfaces
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(); }
I need to achieve the optional < < ighrepo > top contributor (stream < < ighorg > organization)
This method returns ighrepo (getcontributors()) that matches most contributors
I tried this
Optional<IGhRepo> highestContributors(Stream<IGhOrg> organizations){ return organizations .flatMap(IGhOrg::getRepos) .max((repo1,repo2)-> (int)repo1.getContributors().count() - (int)repo2.getContributors().count() ); }
But it gave me
I understand that count () is a terminal operation in stream, but I can't solve this problem. Please help!
thank you
Solution
You didn't specify this content, but it looks like it returned stream <... > Some or all of the interface methods will not return a new stream every time they are called
From an API point of view, this seems problematic to me because it means that each of these streams and a large part of the object function can be used at most once
You can solve the specific problem you encounter by ensuring that the flow of each object is used only once in the method, as shown below:
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); }
Unfortunately, if you want to (for example) print a list of contributors, you seem to be in trouble because the stream returned from getcontributors () has been consumed by the returned ighrepo
You may want to consider having the implementation object return a new stream every time you call the stream return method