5

How to convert following code using stream without using for each loop.

  1. getAllSubjects() returns all List and each Subject has List<Topic>. all List should be combined as List<Topic>.
  2. Needs to get Map<id,topicName> from List<Topic>

Object Model:

Subject
  id,....
  List<Topic>
Topic
  id,name

public Map<String, String> getSubjectIdAndName(final String subjectId) {

    List<Subject> list = getAllSubjects(); // api method returns all subjects
    //NEEDS TO IMPROVE CODE USING STREAMS
    list = list.stream().filter(e -> e.getId().equals(subjectId)).collect(Collectors.toList());
    List<Topic> topicList = new ArrayList<>();
    for (Subject s : list) {
        List<Topic> tlist = s.getTopics();
        topicList.addAll(tlist);
    }
    return topicList.stream().collect(Collectors.toMap(Topic::getId, Topic::getName));

}
4
  • Please show your attempts. Commented Feb 28, 2018 at 10:17
  • 8
    Just remove these intermediate collections into Lists, then, study flatMap and you’re done. In other words, return getAllSubjects() .stream() .filter(e -> e.getId().equals(subjectId)) .flatMap(s -> s.getTopics().stream()) .collect(Collectors.toMap(Topic::getId, Topic::getName)); Commented Feb 28, 2018 at 10:21
  • @Holger seems like the answer rather than a comment. ;) Commented Feb 28, 2018 at 10:26
  • Thank you @Holger Commented Feb 28, 2018 at 10:26

1 Answer 1

9

Use flatMap here, to not stream again. Just notice that this toMap assumes that there will be no duplicate keys (or nulls)

list.stream()
    .filter(e -> subjectId.equals(e.getId()))
    .flatMap(subject -> subject.getTopics().stream())
    .collect(Collectors.toMap(Topic::getId, Topic::getName));
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.