Nuñito Calzada
Nuñito Calzada

Reputation: 2096

Changing the value of a field in a map function of Stream

I want to change the value of a field in a Stream. I am trying to change it in a .map but I got a compilation error

Syntax error on token(s), misplaced construct(s)

the stream:

user.getMenuAlertNotifications()
    .parallelStream()
    .filter(not -> not.getUser().getId()==userId &&
                   notificationList.getIds().contains(not.getId()))
    .map(not -> not.setRead(Boolean.TRUE) -> not)
    .forEach(not -> menuService.save(not));

Upvotes: 5

Views: 223

Answers (2)

Andrew
Andrew

Reputation: 49606

You aren't going to transform the Stream<MenuAlertNotification> to a Stream<Boolean>, so don't use map which is supposed to be a non-interfering, stateless operation:

.filter(...)
.forEach(not -> {
    not.setRead(Boolean.TRUE);
    menuService.save(not);
});

On a side note, not conveys a negative remark which some might find confusing or strange (I did). I would rename that lambda argument to notification, though you can find a shorter option.


By the way, the construction not -> not.set Read(Boolean.TRUE) -> not might be transformed into a perfectly valid expression:

.<Consumer<MenuAlertNotification>>map(not -> n -> n.setRead(Boolean.TRUE))

Upvotes: 11

Alex - GlassEditor.com
Alex - GlassEditor.com

Reputation: 15507

.map(not -> {
    not.setRead(Boolean.TRUE);
    return not;
})

I think peek makes more sense in this case, since you are returning the same element though:

peek(not -> not.setRead(Boolean.TRUE))

You can probably also just use true instead of Boolean.TRUE.

Note that this might not be run for all of the elements in the stream (if it short circuits for example, but it will be for the non-filtered elements in the stream in the question since forEach is the terminal operation).

Also the Function passed to map should be non-interfering and stateless, so you should make sure the setRead method is both of those things.

Upvotes: 1

Related Questions