lukassz
lukassz

Reputation: 3340

Filter and modify list object using java 8 streams

I'am using spring and I defined bean with ArrayList. invites it is a list with Invite objects.

@Getter
public class Invite {

    private String invitee;
    private String email;
    private boolean confirm;
    private String token;
}

This is my data privider class :

@Getter
public class InvitationsData {

    private List<Invite> invites = new ArrayList<>();

    @PostConstruct
    private void initInvites(){
        invites.add(new Invite("John", "[email protected]", false, "6456453"));
        invites.add(new Invite("John", "[email protected]", false, "3252352"));
    }
}

In configuration class I created @Bean from InvitationsData - it works.

In the service I would like to modify one object from list which matches to token string and have set confirm to false.

invitationsData.getInvites()
               .stream()
               .filter(i -> token.equals(i.getToken()))
               .filter(i -> !i.isConfirm())
               .forEach(i -> {
                   i.setConfirm(true);
               });

This stream works fine. Now, when someone call method twice for confirmed object I would like to throw CustomException. How can I do this with this stream? Where can I put orElseThrow?

EDIT:

My current solution. I use peek instead of forEach

invitationsData
                .getInvites()
                .stream()
                .filter(i -> token.equals(i.getToken()))
                .filter(i -> !i.isConfirm())
                .peek(i -> i.setConfirm(true))
                .findFirst()
                .orElseThrow(() -> new InvitationConfirmedException("Error"));

Upvotes: 5

Views: 16838

Answers (2)

Bruno Holanda
Bruno Holanda

Reputation: 1

Just adding to azro answer, for anyone who have a similar scenario, in case you're not sure if the object is on the list, and if it is ok for it not to be, you might prefer to not throw the exception if nothing is found. The code will be like:

getInvites().stream()
        .filter(i -> token.equals(i.getToken()))
        .filter(i -> !i.isConfirm())
        .findAny()
        .ifPresent(i -> i.setConfirm(true));

Upvotes: 0

azro
azro

Reputation: 54148

  • If the token is unique you can do :

    getInvites().stream()
                .filter(i -> token.equals(i.getToken()))
                .filter(i -> !i.isConfirm())
                .findAny()
                .orElseThrow(IllegalArgumentException::new)
                .setConfirm(true);
    
  • If not :

    getInvites().stream()
                .filter(i -> token.equals(i.getToken()))
                .forEach(i -> {
                    if (i.isConfirm()) 
                        throw new CustomException();
                    else 
                        i.setConfirm(true);
                });
    

Upvotes: 3

Related Questions