Java 泛型 Lambda 编译错误

标签 java generics lambda option-type completable-future

我正在尝试为我在 play 框架(2.5.4)中开发的应用程序实现一个非阻塞 DAO 层。它在deleteById()中给了我错误

no instance(s) of variable(s) U exists so that void conforms to U

abstract class BaseDao<E extends BaseModel> {
    JPAApi jpaApi;
    private Class<E> entityClazz;

    BaseDao(JPAApi jpaApi, Class<E> entityClazz) {
        this.jpaApi = jpaApi;
        this.entityClazz = entityClazz;
    }

    public CompletionStage<E> save(E entity) {
        return CompletableFuture.supplyAsync(() -> {
            jpaApi.em().persist(entity);
            return entity;
        });
    }

    public CompletionStage<Optional<E>> findById(String id) {
        return CompletableFuture.supplyAsync(() -> Optional.ofNullable(jpaApi.em().find(entityClazz, id))
        );
    }


    public void deleteById(String id) {
        findById(id).thenApply(
                result -> result.ifPresent(
                        //HERE IS WHERE MY IDE COMPLAINTS 
                        entity -> { 
                            entity.setActive(false);
                            save(entity);
                        }

                )
        );
    }
}

如有任何帮助或建议,我们将不胜感激。

最佳答案

只是为了理解为什么会出现错误

  • Optional.ifPresent()接受一个 Consumer,返回 void
  • CompletionStage.thenApply()需要 Function<T, U> 。返回类型U必须与 lambda 主体的返回类型匹配 - 在本例中 Optional.ifPresent() .
  • void是一个原始类型并且没有盒装的等效类型,因此编译器被难住了。

您可以做的一件事是将表达式 lambda 转换为返回某种值的 block lambda。 例如

    findById(id).thenApply(
            result -> { 
                       result.ifPresent(
                            entity -> { 
                                entity.setActive(false);
                                save(entity);
                            }
                        );
                        return 1;
                    }
    );

这应该允许编译器将类型绑定(bind)在一起 - thenApply()将采取 Function返回 Integer ,而ifPresent()仍然可以拿Consumer返回无效。

或者,也许更好的是,您可以使用 thenAccept()方法CompletionStage() ,它接受 Consumer而不是Function ...

    findById(id).thenAccept(
            result -> result.ifPresent(
                    entity -> { 
                        entity.setActive(false);
                        save(entity);
                    }
            )
    );

关于Java 泛型 Lambda 编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38368459/

相关文章:

java - 如何在struts2中以最少的代码更改更改post请求以获取重定向?

java - 在没有双括号的情况下转换引用变量

c# - 找不到命名空间名称 'p'(是否缺少 using 指令或程序集引用?)

c# - 通用类中的静态列表

java - 我怎样才能抑制匿名 new runnable() 可以用 lambda 代替

java - 如何指定实现类必须包含特定字段?

java - 如何防止具有选项卡行的 JTabbedPane 在选择时对行重新排序?

swift - 如何定义一个 Swift 协议(protocol),强制其采用者自己遵守相关类型?

mysql - 无服务器框架、typescript、nodejs 和 mysql - 错误 : Received packet in the wrong sequence

c++ - void 方法和 lambda 中的常量正确性 'trick'