4

I'm trying to return a boolean inside a Method and i'm using a consumer function. Is there any way to return that value directly inside that Consumer expression?

Here's the Code:

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

    return false;
}

EDIT:

I know that i could create a boolean and change that value but i do not wanna do that.

EDIT:

getResult code:

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());
    }
Tiombo
  • 57
  • 1
  • 4
  • What is that `MySQL` class and is `getResult` asynchronous? If it's asynchronous, what does it return? Can you post its signature? – ernest_k Dec 07 '18 at 20:16
  • 1
    Look at the definition of the `Consumer` method `accept` - its return type is `void`. [Javadoc](https://docs.oracle.com/javase/8/docs/api/java/util/function/Consumer.html). Even the docs say *"Represents an operation that accepts a single input argument and returns no result"* – UninformedUser Dec 07 '18 at 20:17
  • It's just an Consumer returning that ResultSet – Tiombo Dec 07 '18 at 20:18
  • you're probably after a `Predicate` in your method declaration instead of `Consumer`. – Ousmane D. Dec 07 '18 at 20:18
  • Please provide `MySQL.getResult` method signature (i.e. param types and return type) – fps Dec 07 '18 at 20:20
  • @Tombo `Predicate` -> read the Javadoc, it gets a value and returns a value – UninformedUser Dec 07 '18 at 20:20
  • `public static void getResult(String qry, Consumer consumer){ new BukkitRunnable() { @Override public void run() { if(isConnected()) { consumer.accept(Warpixel.getWarpixel().getStats().getResult(qry)); return; } consumer.accept(null); } }.runTaskAsynchronously(Bedwars.getMain()); }` – Tiombo Dec 07 '18 at 20:21
  • only inline code works in comments. why don't you edit the question instead? And you already got the answer, don't use a `Consumer` but a `Prediacte` if it must return a result – UninformedUser Dec 07 '18 at 20:22

3 Answers3

4

No, it's not possible. The lambda expression is an implementation of Consumer.accept and can therefore not return a value because that method is void.

I know that i could create a boolean and change that value but i do not wanna do that.

Not really either. In a lambda expression, you may only reference local variables that are final (making it inherently impossible). You would have to use other techniques (such as a modifiable reference object) to go around this limitation.

An approach that could be suggested is to use a future here:

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

It's important to note that this is a way to block an execution meant to be asynchronous.

ernest_k
  • 44,416
  • 5
  • 53
  • 99
2

Your method getResult is declared as:

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

Where Consumer<ResultSet> is a functional interface representing a function taking a ResultSet as input and has a void return type.

What you're after is called a predicate i.e. Predicate<ResultSet>

Ousmane D.
  • 54,915
  • 8
  • 91
  • 126
  • the problem is that, while this answer is technically correct, it doesn't help the OP because the question is badly posed, please see 2nd edit... The answer is asynchronous – fps Dec 07 '18 at 20:24
  • a Consumer is not returning void. a Consumer returns a value that u can use in a runnable task just like i did. – Tiombo Dec 07 '18 at 20:26
  • @Tiombo 1) You constantly vandalizing your post will not help you nor anyone here so please take your time and include some useful information. 2) look at the [Consumer](https://docs.oracle.com/javase/9/docs/api/java/util/function/Consumer.html) function descriptor. – Ousmane D. Dec 07 '18 at 20:29
  • @FedericoPeraltaSchaffner you're correct and unfortunately, this is what I have to deal with sometimes... – Ousmane D. Dec 07 '18 at 20:30
  • 1
    @Tiombo A consumer doesn't return anything, i.e. it actually returns void. In your case, a consumer *accepts* a value that is *pushed* by another thread when the response is available. Then, you process this response in another thread and the response is passed to you as an argument – fps Dec 07 '18 at 20:30
  • 1
    @Tiombo weird that you don't believe what we're saying here and that don't read the Javadoc of the `Consumer` class...but ok, if you think a `Consumer` in Java returns a value, fair enough, Good luck, ah and please post the code that justifies your statement here as an answer. Which brings me to another question, why did you open the question if a `Consumer` does return a value? – UninformedUser Dec 07 '18 at 20:43
1

It's a lambda expression, which gets executed after the uuidExists method has completed. You have to make an interface used as a callback (just like the function getResult does).

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

It will be executed when you getResult. You have to pass the callback in an additional parameter to uuidExists:

private static boolean uuidExists(UUID uuid, UuidCallback callback)

and call the completed method when you get your result

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

Then, when executing uuidExists you have to make another lambda expression:

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

Hope it helps