Возврат значения метода внутри выражения Consumer

Я пытаюсь вернуть логическое значение внутри метода и использую потребительскую функцию. Есть ли способ вернуть это значение непосредственно внутри этого выражения Consumer?

Вот код:

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());
    }

person Tiombo    schedule 07.12.2018    source источник
comment
Что это за класс MySQL и является ли он getResult асинхронным? Если он асинхронный, что он возвращает? Можете ли вы опубликовать его подпись?   -  person ernest_k    schedule 07.12.2018
comment
Посмотрите на определение метода Consumer accept — его тип возвращаемого значения — void. Javadoc. Даже в документах говорится, что представляет операцию, которая принимает один входной аргумент и не возвращает результата   -  person UninformedUser    schedule 07.12.2018
comment
Это просто Потребитель, возвращающий этот ResultSet   -  person Tiombo    schedule 07.12.2018
comment
вы, вероятно, после Predicate<ResultSet> в объявлении вашего метода вместо Consumer<ResultSet>.   -  person Ousmane D.    schedule 07.12.2018
comment
Пожалуйста, предоставьте сигнатуру метода MySQL.getResult (т.е. типы параметров и тип возвращаемого значения)   -  person fps    schedule 07.12.2018
comment
@Tombo Predicate -› прочитайте Javadoc, он получает значение и возвращает значение   -  person UninformedUser    schedule 07.12.2018
comment
в комментариях работает только встроенный код. почему бы вам не отредактировать вопрос вместо этого? И вы уже получили ответ, используйте не Consumer, а Prediacte, если он должен возвращать результат   -  person UninformedUser    schedule 07.12.2018


Ответы (3)


Нет, это невозможно. Лямбда-выражение является реализацией Consumer.accept и поэтому не может возвращать значение, поскольку этот метод недействителен.

Я знаю, что могу создать логическое значение и изменить это значение, но я не хочу этого делать.

Тоже не особо. В лямбда-выражении вы можете ссылаться только на локальные переменные, которые являются окончательными (что делает это по своей сути невозможным). Чтобы обойти это ограничение, вам придется использовать другие методы (например, модифицируемый ссылочный объект).

Подход, который можно было бы предложить, состоит в том, чтобы использовать будущее здесь:

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()

Важно отметить, что это способ заблокировать выполнение, которое должно быть асинхронным.

person ernest_k    schedule 07.12.2018

Ваш метод getResult объявлен как:

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

Где Consumer<ResultSet> — функциональный интерфейс, представляющий функцию, принимающую ResultSet в качестве входных данных и имеющую возвращаемый тип void.

То, что вам нужно, называется предикатом, т.е. Predicate<ResultSet>

person Ousmane D.    schedule 07.12.2018
comment
проблема в том, что, хотя этот ответ технически правильный, он не помогает ОП, потому что вопрос поставлен неправильно, см. 2-е редактирование... Ответ асинхронный - person fps; 07.12.2018
comment
Потребитель не возвращает пустоту. Потребитель возвращает значение, которое вы можете использовать в выполняемой задаче, как и я. - person Tiombo; 07.12.2018
comment
@Tiombo 1) Вы постоянно разрушаете свой пост, это не поможет ни вам, ни кому-либо здесь, поэтому, пожалуйста, не торопитесь и включите некоторую полезную информацию. 2) посмотрите на Потребитель дескриптор функции. - person Ousmane D.; 07.12.2018
comment
@FedericoPeraltaSchaffner, вы правы, и, к сожалению, иногда мне приходится с этим сталкиваться... - person Ousmane D.; 07.12.2018
comment
@Tiombo Потребитель ничего не возвращает, то есть фактически возвращает void. В вашем случае потребитель принимает значение, которое продвигается другим потоком, когда ответ доступен. Затем вы обрабатываете этот ответ в другом потоке, и ответ передается вам в качестве аргумента. - person fps; 07.12.2018
comment
@Tiombo странно, что вы не верите тому, что мы здесь говорим, и не читаете Javadoc класса Consumer ... но ладно, если вы думаете, что Consumer в Java возвращает значение, справедливо, удачи, ах, и, пожалуйста, опубликуйте код, который оправдывает ваше утверждение здесь в качестве ответа. Что подводит меня к другому вопросу, почему вы открыли вопрос, если Consumer действительно возвращает значение? - person UninformedUser; 07.12.2018

Это лямбда-выражение, которое выполняется после завершения метода 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 вам нужно сделать еще одно лямбда-выражение:

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

Надеюсь, поможет

person Oranż Metylowy    schedule 07.12.2018
comment
Спасибо понял :D - person Tiombo; 07.12.2018