【问题标题】:Returning Method value inside a Consumer expression在消费者表达式中返回方法值
【发布时间】:2019-05-09 14:43:27
【问题描述】:

我正在尝试在方法中返回一个布尔值,并且我正在使用消费者函数。 有没有办法直接在该消费者表达式中返回该值?

这是代码:

private static boolean uuidExists(UUID uuid) {
    MySQL.getResult("", rs -> {
        try {
            if(rs.next()){
                return rs.getString("UUID") != null;
            }
        } catch (SQLException e) {
        }
    });

    return false;
}

编辑:

我知道我可以创建一个布尔值并更改该值,但我不想这样做。

编辑:

获取结果代码:

public static void getResult(String qry, Consumer<ResultSet> consumer){
        new BukkitRunnable() {
            @Override
            public void run() {
                if(isConnected()) {
                    consumer.accept(Warpixel.getWarpixel().getStats().getResult(qry));
                    return;
                }
                consumer.accept(null);
            }
        }.runTaskAsynchronously(Bedwars.getMain());
    }

【问题讨论】:

  • MySQL 类是什么,getResult 是异步的?如果它是异步的,它会返回什么?你能张贴它的签名吗?
  • 查看Consumer方法accept的定义——它的返回类型是voidJavadoc。甚至文档都说“表示接受单个输入参数并且不返回任何结果的操作”
  • 只是一个消费者返回那个 ResultSet
  • 您可能在方法声明中使用Predicate&lt;ResultSet&gt; 而不是Consumer&lt;ResultSet&gt;
  • 请提供MySQL.getResult方法签名(即参数类型和返回类型)

标签: java return consumer


【解决方案1】:

不,这是不可能的。 lambda 表达式是Consumer.accept 的实现,因此不能返回值,因为该方法是无效的。

我知道我可以创建一个布尔值并更改该值,但我不想这样做。

也不是。在 lambda 表达式中,您只能引用最终的局部变量(这在本质上是不可能的)。您必须使用其他技术(例如可修改的引用对象)来解决此限制。

可以建议的一种方法是在这里使用未来:

CompletableFuture<Boolean> future = new CompletableFuture<Boolean>();

MySQL.getResult("", rs -> {
    try {
        if(rs.next()){
            future.complete(rs.getString("UUID") != null);
        }
    } catch (SQLException e) {
        //handle exception
    }

    future.complete(false); //mind this default value
});

return future.join(); //this will block until the `Consumer` calls complete()

请务必注意,这是一种阻止异步执行的方法。

【讨论】:

    【解决方案2】:

    您的方法getResult 声明为:

    void getResult(String qry, Consumer<ResultSet> consumer){ ... }
    

    其中Consumer&lt;ResultSet&gt; 是一个函数式接口,表示一个以ResultSet 作为输入并具有void 返回类型的函数。

    您所追求的称为谓词,即Predicate&lt;ResultSet&gt;

    【讨论】:

    • 问题是,虽然这个答案在技术上是正确的,但它对 OP 没有帮助,因为问题提出的很糟糕,请参阅第二次编辑...答案是异步的
    • 消费者没有返回无效。消费者返回一个值,您可以像我一样在可运行的任务中使用它。
    • @Tiombo 1) 你不断破坏你的帖子对你和这里的任何人都没有帮助,所以请慢慢来,并提供一些有用的信息。 2)查看Consumer函数描述符。
    • @Tiombo 消费者不返回任何东西,即它实际上返回 void。在您的情况下,当响应可用时,消费者接受另一个线程推送的值。然后,您在另一个线程中处理此响应,并将响应作为参数传递给您
    • @Tiombo 很奇怪,你不相信我们在这里说的话,也没有阅读 Consumer 类的 Javadoc ......但是好吧,如果你认为 Consumer在Java中返回一个值,足够公平,祝你好运,啊,请在此处发布证明您的陈述合理的代码作为答案。这让我想到了另一个问题,如果 Consumer 确实返回值,你为什么要打开这个问题?
    【解决方案3】:

    这是一个 lambda 表达式,uuidExists 方法完成后执行。您必须创建一个用作回调的接口(就像函数 getResult 所做的那样)。

    public interface UuidCallback {
        void onCompleted(boolean uuidExists);
    }
    

    它会在你getResult时执行。您必须将附加参数中的回调传递给uuidExists

    private static boolean uuidExists(UUID uuid, UuidCallback callback)
    

    当你得到结果时调用完成的方法

    if(rs.next()){
        callback.onCompleted(rs.getString("UUID") != null);
    }
    

    然后,在执行uuidExists 时,你必须创建另一个 lambda 表达式:

    uuidExists(someUUIDInstance, uuidExists -> {
        // boolean uuidExists now has your result
    });
    

    希望对你有帮助

    【讨论】:

    • 谢谢我明白了:D
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-12
    • 2020-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多