Java 泛型 Lambda 编译错误

Java Generics Lambda Compilation Error

我正在尝试为我在 play framework(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() 需要一个消费者,returns void
  • CompletionStage.thenApply()需要一个Function<T, U>。 return 类型 U 必须匹配 lambda 主体的 return 类型 - 在本例中为 Optional.ifPresent().
  • void 是原始类型,没有盒装等效项,因此编译器被难住了。

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

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

这应该允许编译器将类型绑定在一起 - thenApply() 将采用 Function returning 和 Integer,而 ifPresent() 是仍然可以 Consumer return 无效。

或者,您可以在 CompletionStage() 上使用 thenAccept() 方法,它接受 Consumer 而不是 Function...

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