首页 > 解决方案 > 如何在集合和数组列表上使用 lambda 表达式

问题描述

我有一个比较两个类的私有无效代码。在这个典型的代码中,我希望能够在最初不使用 lambda 的地方使用/应用 lambda 表达式。尝试了几种方法,如地图、流或过滤器,但似乎没有得到代码的确切格式,这是我要应用 lambda 表达式的代码。只需要此代码

     private void checkPrivileges(User user) {
            Collection<Role> roles = user.getAllRoles();
            List<String> requiredPrivs = new ArrayList<>();
            for (Role r : roles) {

                if (r.getRole().equals(RoleConstants.SUPERUSER)
                        && !Context.hasPrivilege(PrivilegeConstants.ASSIGN_SYSTEM_DEVELOPER_ROLE)) {
                    throw new APIException("User.you.must.have.role", new Object[] { RoleConstants.SUPERUSER });
                }
                if (r.getPrivileges() != null) {
                    for (Privilege p : r.getPrivileges()) {
                        if (!Context.hasPrivilege(p.getPrivilege())) {
                            requiredPrivs.add(p.getPrivilege());
                        }
                    }
                }
            }

            if (requiredPrivs.size() == 1) {
                throw new APIException("User.you.must.have.privilege", new Object[] { requiredPrivs.get(0) });
            } else if (requiredPrivs.size() > 1) {
                StringBuilder txt = new StringBuilder("You must have the following privileges in order to assign them: ");
                for (String s : requiredPrivs) {
                    txt.append(s).append(", ");
                }
                throw new APIException(text.substring(0, text.length() - 2));
            }
        }

它有对应的 Roles.java 和 Privilege.java 类。我的问题是仅在 void 类上使用 lambda 表达式。这是我做的试验,但它是我任务的一半

role.getPrivileges().stream()
    .filter(()->{
          return Optional.of(privileges)
              .filter(given ->given.p.get privileges())
              .getOrElse("privilege required:" +p)});

标签: lambdajava-8

解决方案


我会展平 for-if-for 层次结构并提取一个常量 + 一个检查方法,例如:

private static final String ERROR_FORMAT = "You must have the following privileges in order to assign them: %s";

private void checkPrivileges(User user) {
    List<String> requiredPrivs = new ArrayList<>();
    for (Role r : user.getAllRoles()) {
        checkSuperUserPrivilege(r);
        Iterable<Privilege> privileges = r.getPrivileges() != null ? r.getPrivileges() : Collections.emptySet();
        for (Privilege p : privileges) {
            if (!Context.hasPrivilege(p.getPrivilege())) {
                requiredPrivs.add(p.getPrivilege());
            }
        }
    }
    if (requiredPrivs.size() == 1) {
        throw new APIException("User.you.must.have.privilege", new Object[] { requiredPrivs.get(0) });
    } else if (requiredPrivs.size() > 1) {
        throw new APIException(String.format(ERROR_FORMAT, String.join(", ", requiredPrivs)));
    }
}

private void checkSuperUserPrivilege(Role r) {
    if(r.getRole().equals(RoleConstants.SUPERUSER)
            && !Context.hasPrivilege(PrivilegeConstants.ASSIGN_SYSTEM_DEVELOPER_ROLE)) {
        throw new APIException("User.you.must.have.role", new Object[] { RoleConstants.SUPERUSER });
    }
}

正如我在评论中所说,使用 Streams 处理这个问题是一个坏主意,但你可以这样:

private static final String ERROR_FORMAT = "You must have the following privileges in order to assign them: %s";

private void checkPrivileges(User user) {
    List<String> requiredPrivs = user.getAllRoles().stream()
            .peek(this::checkSuperUserPrivilege)
            .map(Role::getPrivileges)
            .filter(Objects::nonNull)
            .flatMap(Collection::stream)
            .map(Privilege::getPrivilege)
            .filter(p -> !Context.hasPrivilege(p))
            .collect(Collectors.toList());
    if (requiredPrivs.size() == 1) {
        throw new APIException("User.you.must.have.privilege", new Object[] { requiredPrivs.get(0) });
    } else if (requiredPrivs.size() > 1) {
        throw new APIException(String.format(ERROR_FORMAT, String.join(", ", requiredPrivs)));
    }
}

private void checkSuperUserPrivilege(Role r) {
    if(r.getRole().equals(RoleConstants.SUPERUSER)
            && !Context.hasPrivilege(PrivilegeConstants.ASSIGN_SYSTEM_DEVELOPER_ROLE)) {
        throw new APIException("User.you.must.have.role", new Object[] { RoleConstants.SUPERUSER });
    }
}

推荐阅读