java - Lambda 表示法 - 尝试重构但遇到问题

标签 java playframework lambda java-8

我有许多映射到服务器请求的方法。请求使用 promises (来自 Play Framework)在未来的某个时间返回响应。这是我的一项操作的示例:

public static Promise<Result> someAction() {
    MyBean data = new MyBean(getData(request().body()));
    Promise<MyReq> promise = Promise.promise(() -> new MyReq(data));
    return promise.map((MyReq req) -> ok(req.getResponse()));
}

请注意 MyReq延伸MyAbstractReq<T> .

我希望做的是能够从所有操作方法中取出所有通用代码,并将其捆绑到一个通用的 handleRequest 中。方法。但是,我很难理解 Lambda 表示法,无法修改代码以满足我的目的。

我明白 () -> new MyReq(data)基本上意味着 (arg1, arg2, ...) -> { body }可以这样写(我认为):

MyBean data = new MyBean(getData(request().body()));

// Anonymous Functional Interface
MyFunction f = new MyFunction() {      
    @Override
    public void getReq(){
        return new MyReq(data);
    }
};

或者类似的东西。

但我想要实现的是类似这样的东西(无法编译,但我希望它能充分说明我想要实现的目标):

public static Promise<Result> handleRequest(MyAbstractReq<?> req) {
    Promise<MyAbstractReq<?>> promise = Promise.promise(() -> req);
    return promise.map(() -> ok(req.getResponse()));
}

每个 Action 看起来像这样:

public static Promise<Result> someAction() {
    MyBean data = new MyBean(getData(request().body()));
    return handleRequest(new MyReq(data));
}

有人可以指出我在 Lambda 表示法方面缺少什么,并解释我如何才能实现我想要做的事情。

更新

我得到的错误是

Lambda expression's signature does not match the signature of the functional interface method apply(? super MyAbstractReq<?>)

我猜那是因为语法不正确,这只是我第一次天真的尝试重构它。

req.getResponse()方法并不真正相关,因为它只是生成一个 Json 对象(ObjectNode - Jackson 更快的 xml),它可以被 ok() 使用。创建 Result 的方法

更新 2

关于使用 handleRequest(MyAbstractReq<T> req)我最初确实有这个,但错误基本上是一样的。

Lambda expression's signature does not match the signature of the functional interface method apply(? super MyAbstractReq<T>)

更新 3

请原谅。错误在 return promise.map(() -> ok(req.getResponse()));

更新 4

我可能应该提到我知道如何通过更改 handleRequest() 来解决问题。方法:

public static Promise<Result> handleRequest(MyAbstractReq<?> req) {
    Promise<MyAbstractReq<?>> promise = Promise.promise(() -> req);
    return promise.map((MyAbstractReq<?> notUsed) -> ok(req.getResponse()));
}

但是return promise.map((MyAbstractReq<?> notUsed) -> ok(req.getResponse()));这行感觉不对参数为 MyAbstractReq<?>从未使用过。

我对 Lambda 表达式的表示法了解不够,无法判断这是否不是实现我想要的目标的最佳方式(我没有提及它是因为我想看看如果没有我的领导人们会有什么建议一个答案)。

最佳答案

在您的初始代码中

public static Promise<Result> someAction() {
    MyBean data = new MyBean(getData(request().body()));
    Promise<MyReq> promise = Promise.promise(() -> new MyReq(data));
    return promise.map((MyReq req) -> ok(req.getResponse()));
}

一切都按预期工作,因为 map 得到一个指定如何处理参数 req 的函数。但是在您重构的代码中,您突然尝试从外部范围访问变量而不是保持逻辑:

public static Promise<Result> handleRequest(MyAbstractReq<?> req) {
    Promise<MyAbstractReq<?>> promise = Promise.promise(() -> req);
    // the following function refers to handleRequest’s parameter instead of its argument
    return promise.map((MyAbstractReq<?> notUsed) -> ok(req.getResponse()));
}

这在这种特殊情况下有效,但确实如您的感觉所告诉您的那样错误。

在这里保持原来的逻辑:

public static Promise<Result> handleRequest(MyAbstractReq<?> req) {
    Promise<MyAbstractReq<?>> promise = Promise.promise(() -> req);
    // arg is unrelated to req here though both variables happen to have to same contents
    return promise.map(arg -> ok(arg.getResponse()));
}

但它仍然有点奇怪,因为 promise 是围绕一个已经存在的对象构建的,而不是构建它。也许你想要

public static Promise<Result> handleRequest(Function0<MyAbstractReq<?>> supplier) {
    Promise<MyAbstractReq<?>> promise = Promise.promise(supplier);
    return promise.map(arg -> ok(arg.getResponse()));
}

所以你可以这样调用它

handleRequest( ()-> new MyReq(new MyBean(getData(request().body()))) );

Promise 将真正涵盖整个操作。

关于java - Lambda 表示法 - 尝试重构但遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29124205/

相关文章:

java正则表达式匹配&[文本]

java - 如何在 Java 1.6 中使用 ECC 私钥?

scala - 在交易中包装测试

scala - Play Framework : Slick does not know how to map the given types

java - 使用通用供应商和 lambda 进行类型检查

c# - 在 Monotouch 中编译 lambda 并在设备上调用委托(delegate)

Java 8 Lambda 表达式

java - 不保存子实体

java - 如何从 JSON 响应中提取 boolean 值?

scala - 在 Scala 项目中,如何将 play 框架用作库