java help in function return value

Viewed 45

Do I need to interface here or is it something else?

And if so ... how do I do that? Because it returns to me the value that has nothing in it and I want it to return to me the value that I have already set values for. Thanks

public double[] findbyidTodo(Context context , String loc) {

    double[] list =  new double[]{};

        new Thread(new Runnable() {
            @Override
            public void run() {
                Todo todo = TodoRoomDatabase.getInstance(context)
                        .todoDao()
                        .findTodoById(loc);

                if (todo != null) {
                    list = new double[]{todo.getLatitude(), todo.getLongitude()};

                }

            }

        }).start();
        return list; // is return the null and not the new list

    }
2 Answers

The basic problem here is that you are trying to return the result of an asynchronous computation synchronously. It is not possible. You can't return something that you don't have yet!

So what should you?

The simple solution is to do the database operation synchronously; i.e. do it in the current thread rather than using new Thread(...).start(). Just move the code that is in your run() method inline.

(You would get the same effect by calling join() on the thread before the final return in you code. But you would be creating and destroying a thread for no good reason. It is inefficient.)

However, if you need to do the database operation asynchronously, you could use a CompletableFuture (javadoc) as follows:

public CompletableFuture<double[]> findbyidTodo(Context context , String loc) {

    final CompletableFuture<double[]> future =  new CompletableFuture<>();

    new Thread(new Runnable() {
        @Override
        public void run() {
            Todo todo = TodoRoomDatabase.getInstance(context)
                    .todoDao()
                    .findTodoById(loc);

            if (todo != null) {
                future.complete(new double[]{todo.getLatitude(), todo.getLongitude()});
            } else {
                future.complete(null);
            }

    }).start();
    return future;
}

Then the caller can do this:

CompletableFuture<double[]> future = findbyidTodo(...);

// Do some other stuff

double[] result = future.get();   // This blocks until the future has been completed.

Note that it is only worthwhile doing this if the database call is likely to take a significant amount of time, AND there actually is "other stuff" for the calling thread to do while the database call is in progress. If not ... then it is better to do the database operation synchronously.

Finally, if you are going to do this asynchronously, it would be more efficient to use a thread pool or executor service rather than creating a new thread for each database operation. Look at the javadocs for ExecutorService and Executors. (Creating and destroying threads is relatively expensive.)

It happens because of asynchrony.

This is an asynchronous call. This means that it will get started but the code won't wait for it.

Thread(new Runnable(){}

So if you do this:

double[] list =  new double[]{};

Thread(new Runnable(){}

return list;

Java won't wait for the thread to be finished and returns your still empty array.

Have a look at this article to solve the problem:

Related