4

Count number of content using stream

class Subject {
  private String id;
  private String name;
  private List<Unit> units;
}

class Unit {
  private String id;
  private String name;
  private List<Topic> topics;
}

class Topic {
  private String id;
  private String name;
  private List<Content> contents;
}

class Content {
  private String id;
  private String contentType;
  private SubTopic subtopic;
}

With Java 8 and Streams I want the count of the Content elements which is of contentType equal to the video.

To count topic I tried this:

int topicCount = subject.getUnits().stream()
    .map(Unit::getTopics)
    .filter(topics -> topics != null)
    .mapToInt(List::size)
    .sum();
1
  • 1
    are you really willing to check the List being null? when you wrote .filter(topics -> topics != null)? I mean I can read it, but you should avoid that. (assigning null to a List) Commented Apr 9, 2020 at 14:04

2 Answers 2

4

You could flat map the nested elements and count them:

long videoContentCount = 
    subject.getUnits()
           .stream()
           .flatMap(u -> u.getTopics().stream())
           .flatMap(t -> t.getContents().stream())
           .filter(c -> c.getCountetType().equals("video"))
           .count();
Sign up to request clarification or add additional context in comments.

3 Comments

flatMap(Unit::getTopics), wouldn't that require getTopics to return a Stream?
@Naman arg, yes, I forgot to stream it, thanks for noticing! Edited and fixed.
Adding extra point for this. You could use enum for content type, instead of String literals for better type safety which would avoid NPE for getContentType
2

You use streams as below,

subject.getUnits()
        .stream()
        .map(Unit::getTopics)
        .flatMap(List::stream)
        .map(Topic::getContents)
        .flatMap(List::stream)
        .map(Content::getContentType)
        .filter("video"::equals)
        .count();

You can avoid map,

subject.getUnits()
        .stream()
        .flatMap(e->e.getTopics().stream())
        .flatMap(e->e.getContents().stream())
        .map(Content::getContentType)
        .filter("video"::equals)
        .count();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.