Reputation: 171
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}]
]
Upvotes: 0
Views: 73
Reputation: 274520
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());
Upvotes: 2