首页 > 解决方案 > 如何返回 lambda 函数并通过作为参数传递给 Java 8 中的方法来使用?为什么我不能使用 :: 运算符?

问题描述

我试图在我的 Role 类中实现自定义验证谓词。即isInRealm()它返回一个Predicate<String>并且是一个基本的,只是为了表明我的意图。

public enum Role {
    USER("ROLE_user", 1),
    CUSTOMER("ROLE_customer", 2),
//...
    public static Predicate<String> isInRealm() {
         return role -> Arrays.stream(values()).anyMatch(value -> value.value.equals(role));
    }
}

我可以在客户端类中定义谓词,也可以直接作为 lambda 表达式或方法引用传递。(1)(2) 下面,有它们的案例,我已经注意到哪个有效或无效。

public class UserService {

//...

public User getUserProfile() {
        //validateUser(Role.isInRealm());    -> OK
        validateUser(Role::isInRealm);       -> NOK
        validateUser(r -> Role.isInRealm()); -> NOK
        //validateUser(role -> Arrays.stream(Role.values()).anyMatch(value -> value.equals(role))); -> OK (1)
        //validateUser(s -> true); -> OK (2)
//...
}

private void validateUser(Predicate<String> predicate) {
        Authentication principal = SecurityContextHolder.getContext().getAuthentication();
        String role = utils.getRoles(principal).findFirst().get().getAuthority();
        if (!predicate.test(role)) {
            throw new ForbiddenAccessException(ResponseCode.FORBIDDEN_ACCESS.getMessage());
        }
    }
}

我对如何获取Function方法返回的句柄感到困惑。

虽然isInRealm()方法将 lambda 表达式作为谓词返回,但为什么我不能用Role::isInRealmor调用它r -> Role.isInRealm()?当我尝试时,我得到bad return type in lambda expression: Predicate<String> cannot be converted to boolean.

当我直接在客户端代码中传递 lambda 表达式时,它可以工作,但在这种情况下,我需要使用validateUser(Role.isInRealm()). 为什么会这样?

Role.isInRealm()这是有道理的,因为该方法返回一个函数对象,我们正在获取该对象,但由于 Java 8 流 API 函数不是一流的语言结构,我无法完全掌握使用::.

当我们使用点或双冒号时,后面发生了什么?

标签: javalambdajava-8functional-programmingjava-stream

解决方案


您将 lambda 与调用混合在一起。在以下示例isInRealm中调用,并使用返回值 (lambda):

validateUser(Role.isInRealm());

所以有效地role -> Arrays.stream(values()).anyMatch(value -> value.value.equals(role));传递给validateUser方法。

在接下来的两个示例中:

validateUser(Role::isInRealm);
validateUser(r -> Role.isInRealm());

您正在尝试传递 lambdas(供应商),当被调用时将返回您正在寻找的 lambda。你没有传递Predicateto validateUser


推荐阅读