使用Java 8流过滤和修改列表对象

5

我正在使用Spring框架,并定义了一个带有ArrayList的Bean。 invites是一个包含Invite对象的列表。

@Getter
public class Invite {

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

这是我的数据提供者类:
@Getter
public class InvitationsData {

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

    @PostConstruct
    private void initInvites(){
        invites.add(new Invite("John", "john@john.com", false, "6456453"));
        invites.add(new Invite("John", "john@john.com", false, "3252352"));
    }
}

在配置类中,我创建了一个来自InvitationsData的@Bean - 它可以工作。
在服务中,我想修改列表中与令牌字符串匹配并将confirm设置为false的一个对象。
invitationsData.getInvites()
               .stream()
               .filter(i -> token.equals(i.getToken()))
               .filter(i -> !i.isConfirm())
               .forEach(i -> {
                   i.setConfirm(true);
               });

这个流运行良好。现在,当有人两次调用确认对象的方法时,我想抛出CustomException。如何在这个流中实现?我应该在哪里使用orElseThrow

编辑:

我的当前解决方案。我使用peek而不是forEach

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

令牌是唯一的还是可以有多个邀请使用相同的令牌? - azro
你可以将检查放在 forEach 内部。 - Adam Siemion
1
@azro令牌是唯一的。 - lukassz
2个回答

3
  • 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);
                });
    

1
当令牌不唯一时,代码将跳过其他有效的令牌,一旦抛出异常..除非在foreach中立即捕获。 - Kartik

0
只是补充一下azro的回答,对于有类似情况的人来说,如果你不确定对象是否在列表中,并且即使没有也可以接受,那么你可能更愿意在找不到任何内容时不抛出异常。代码将如下所示:
getInvites().stream()
        .filter(i -> token.equals(i.getToken()))
        .filter(i -> !i.isConfirm())
        .findAny()
        .ifPresent(i -> i.setConfirm(true));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接