0

I have a nested for loop. Every message class have relation to MessageDetail class (one to many relation) and I want to convert below for loop to stream.

for (Message m:messages){
        System.out.println(m.getText());
        for (MessageDetail m2:m.getMessageDetails()){
            System.out.println(m2.getId+m2.getStatus());
        }
    }

I try this code but i can not show e.getText in upper level.

messages.stream().flatMap(e-> e.getMessageDetails().stream().map(
                e2->e.getText()+"-->{"+e2.getId()+"," +e2.getStatus()+"}"
                )).collect(Collectors.toList());

The output like:

[
 Hi-->{1,OK},
 Hi-->{2,OK},
 Hi-->{4,NOT_DELIVER},
 Bye-->{5,OK},
 Bye-->{6,NOT_DELIVER},
 Bye-->{7,NOT_DELIVER},
]

But I want to like this:

  [
    Hi [ {2,OK},{3,OK},{4,NOT_DELIVER}]
    Bye[ {5,OK},{6,NOT_DELIVER},{7,NOT_DELIVER}]
  ]
1
  • messages.stream().flatMap(e-> { System.out.println(e.getText()); return e.getMessageDetails().stream();}).map( e->e.getStatus()+e.getMessage()).forEach(System.out::println); Commented Jul 30, 2019 at 8:40

1 Answer 1

2

flatMap should be used only when you want each element in your stream to transform into multiple elements in the resulting stream. Here, each Message in the original stream correspond to one String in the resulting list, so you should not use flatMap.

Use map instead:

messages.stream().map(
    e -> e.getText() + "-->" + 
        e.getMessageDetails().stream().map(d -> "{" + d.getId() + ", " + d.getStatus() + "}").collect(Collectors.toList()).toString())
    .collect(Collectors.toList());

If you can edit the Message class and whatever class getMessageDetails returns, I suggest that you override their toString methods (or write your own method that returns a string) instead:

// Message class:
public String toString() {
    return getText() + "-->" + getMessageDetails().toString();
}

// MessageDetails class
public String toString() {
    return "{" + getId() + ", " + getStatus() + "}";
}

Then you could just do:

messages.stream().map(Message::toString).collect(Collectors.toList());
Sign up to request clarification or add additional context in comments.

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.