wrapping String in scala Future from java code - java

I have the following method for testing:
public scala.concurrent.Future<String> send() {
return "OK"; //error - should wrap with future
}
How can I make it return a scala future (this is java code, so didn't find any example)?

It's easy if you are working with the Scala 2.12.x library.
In Scala you would write Future(doSomeStuff()). Or simply Future.successful("OK") if you really only want to wrap a literal in a Future.
In Java that translates to one of these:
import scala.concurrent.*;
public Future<String> send1() {
return Future.apply( () -> doSomeStuff(), ExecutionContext.global());
}
public Future<String> send2(ExecutionContext ec) {
return Future.apply( () -> doSomeStuff(), ec);
}
public Future<String> send3() {
return Future.successful("OK");
}
If you have more complex code to run than simply "OK" you'll have to use send1 or send2. Which of those you want depends on whether you want to use the default ExecutionContext or let the caller decide.
If your Scala version is lower than 2.12.0, the send1 method from above will look something like this:
import scala.concurrent.*;
import scala.runtime.AbstractFunction0;
public Future<String> send1() {
return Future$.MODULE$.apply( new AbstractFunction0<String>() {
public String apply() {
return doSomeStuff();
}
}, ExecutionContext$.MODULE$.global());
}

Related

Java Supplier<> defined as lambda. Need help understanding how this code even runs

Sorry for the somewhat unclear title but hopefully you'll see soon that it wasn't so easy to come up with a better one :)
So I have this interface that extends the Java Supplier #FunctionalInterface by defining one new method and also a default implementation of the Supplier.get() method. My default impl of .get() only wraps a call to the other method in some exception handling.
Then in my code I have different "versions" of this Supplier initialized using lambda notation.
Ex: SomeSupplier s = () -> doSomething();
Not sure why I even tried this because logically I don't understand how this even works, which it does. In my mind when I define my supplier using lambda like this I'm essentially overriding the Supplier.get() method. So how is it that in practice it seems to override my SomeSupplier.getSome() method? And leave the default impl of the .get() method intact?
What am I missing here?
Working example code:
public static void main(String[] args) throws InterruptedException {
SomeSupplier s = () -> getSomeOrException(); // "implements" the Supplier.get(), right?
for (int i = 0; i < 100; i++) {
System.out.println(s.get()); // => "Some!" or "null"
Thread.sleep(2);
}
}
private static String getSomeOrException() throws SomeCheckedException {
if (System.currentTimeMillis() % 10 == 0) {
throw new SomeCheckedException("10 %!");
}
return "Some!";
}
private interface SomeSupplier extends Supplier<String> {
#Override
default String get() {
try {
return getSome();
}
catch (SomeCheckedException e) {
return e.getMessage();
}
}
String getSome() throws SomeCheckedException; // How is this overridden/implemented?
}
private static class SomeCheckedException extends Exception {
public SomeCheckedException(String message) {
super(message);
}
}
}```
Your mistake is that assuming that if a Lambda of a Supplier implements get then a lambda of a SomeSupplier must also implement get.
But instead a Lambda will always implement the single abstract method of an interface* it's about to implement. In Supplier that's get. Your SomeSupplier however has implemented get (with a default method). Therefore getSome() becomes the single abstract method of the functional interface SomeSupplier. So this line:
SomeSupplier s = () -> getSomeOrException();
is roughly analogous to this:
SomeSupplier s = new SomeSupplier() {
String getSome() throws SomeCheckedException() {
return getSomeOrException();
}
};
Note that this implements getSome and not the underlying get method.
*: This is also why functional interfaces can only ever have one abstract method: there's no fallback logic to pick one option if more than one such method exists for a given target type.

How do I pass a lambda from Java to a Kotlin method?

Can I call this Kotlin method from Java?
fun foo(() -> Unit)
If so, what's the syntax?
You need to create instance of Function0:
foo(new Function0<Unit>() {
#Override
public Unit invoke() {
// Here should be a code you need
return null;
}
});
or if you use Java 8 it can be simplified
foo(() -> {
// Here should be a code you need
return null;
});
You can call this but need to be careful of the return types. If your Kotlin function returns a Unit, Java will either need to return Unit or null, because void is not quite the same as Unit.
My example that worked:
foo(() -> {
System.out.println("Hi");
return null;
});
Or, if you want to be really explicit about Unit...
foo(() -> {
System.out.println("Hi");
return Unit.INSTANCE;
});
I totally agree with Andrew's Answer, There is a better way to approach
You need to see generated Kotlin Bytecode -> Decompile it
In your case it looks something like this:
public static final void foo(#NotNull Function0 acceptLambda) {
Intrinsics.checkNotNullParameter(acceptLambda, "acceptLambda");
}
now you know in order to call this function form Java you need to create instance of Function0 something like this
foo(new Function0<Unit>() {
#Override
public Unit invoke() {
// Your Code
return null;
}
});

Java extension methods for LiveData

In Kotlin there's an extension method observeOnce (https://code.luasoftware.com/tutorials/android/android-livedata-observe-once-only-kotlin/) which is the behaviour I'm looking to replicate in Java. It's to my understanding from googling that you can't use Kotlin extension methods in java (may be wrong), so I've got two options of using SingleEventLiveData which I've implemented and am not keen on, and removing my observer once used;
final LiveData<List<String>> stringsLiveData = mViewModel.getStrings();
stringsliveData.observe(getViewLifecycleOwner(), strings -> {
// Do stuff with data here
stringsLiveData.removeObservers(getViewLifecycleOwner());
});
Is there an equivilant method that can be used as the link above so;
mViewModel.getStrings().observeOnce(getViewLifecycleOwner(), strings -> {
//Do stuff here
});
Edit: As per the accepted answer below (modified to compile) I've got;
class LiveDataUtils {
public static <T> void observeOnce(LiveData<T> liveData, Observer<T> observer) {
liveData.observeForever(o -> {
liveData.removeObserver(observer);
observer.onChanged(o);
});
}
}
and a simple usage of this;
LiveDataUtils.observeOnce(
mViewModel.getStrings(),
strings -> {
// Do some work here
}
);
Every Kotlin extension function is resolved statically, which means that you can do the same in Java by using static functions. It is not as readable or as intuitive as the extension functions, but it does the same job.
Create a util class with a static method:
public class LiveDataUtils {
public static <T> void observeOnce(LiveData<T> liveData, Observer<T> observer) {
liveData.observeForever(new Observer<T>() {
#Override
public void onChanged(T t) {
liveData.removeObserver(this);
observer.onChanged(t);
}
});
}
}
I haven't tested the code, so it might have some errors. The point was to show you how you can replace extension functions in Java.
EDIT: Updated according to follow up by #Marek Potkan, since this is the accepted answer. As I mentioned, I haven't tested the code and I provided a wrong reference by mistake.
#deluxe1 answer wouldn't work. It is removing observer called observer, but that's not the one which is used in the observeForever method. Expanded version should be used instead of the lambda function here:
public static <T> void observeOnce(LiveData<T> liveData, Observer<T> observer) {
liveData.observeForever(new Observer<T>() {
#Override
public void onChanged(T t) {
liveData.removeObserver(this);
observer.onChanged(t);
}
});
}
I have tested both approaches.

Maybe switchIfEmpty lazy evaluation

I use Maybe switchIfEmpty method to provide an alternate result if the source Maybe is empty. However, I would like the alternate source to be executed only when the source is empty and not execute it when the source is not empty.
In the following example I would like to avoid execution of costlyFallback if the source returned non-empty Maybe. The current implementation always calls it because it is required to be passed to switchIfEmpty method. Maybe.fromCallable looks promising, however it will work only with callables which exludes returning a Maybe.empty. Any hints are appreciated. Would be nice if switchIfEmpty would accept some lazily evaluated Maybe provider.
public class StartRxMaybe {
public static void main(String... args) {
System.out.println(new StartRxMaybe().start().blockingGet());
}
private Maybe<Integer> start() {
return func()
.switchIfEmpty(costlyFallback());
}
private Maybe<Integer> func() {
System.out.println("Non-empty maybe returned");
return Maybe.just(1);
}
private Maybe<Integer> costlyFallback() {
System.out.println("Fallback executed anyway");
return LocalDate.now().getMonth() == Month.JULY
? Maybe.just(2)
: Maybe.empty();
}
}
I think I found the solution. Using Maybe.defer does the trick and allows to pass the supplier:
private Maybe<Integer> start() {
return func()
.switchIfEmpty(Maybe.defer(this::costlyFallback));
}
Thanks to #nosalan, here is my solution for Kotlin:
fun getOperator(id: Int): Single<Operator> {
return db.getOperator(id)
.switchIfEmpty(Single.defer { api.getOperators }
.flattenAsFlowable { it }
// etc.
)
}
Note {} instead of () in defer.

How to surround a callback invocation with another piece of code in a best way?

I have a simple, functional interface:
public interface Callback<T> {
void invoke(T param);
}
I make many asynchronous operations like:
public void getSubfolders(Folder folder, Callback<FolderList> result){
asyncExecutor.submit(() -> {
FolderList list = folder.get_SubFolders();
result.invoke(list);
});
}
The results must be processed on a main thread. For that, I have a JavaFX method:
Platform.runLater(Runnable task);
Which makes my code a mess like this one (and this pattern is repeated in 50 other methods):
public void getSubfolders(Folder folder, Callback<FolderList> result){
asyncExecutor.submit(() -> {
FolderList list = folder.get_SubFolders();
Platform.runLater(() -> result.invoke(list));
});
}
I'd like to wrap each callback invocation with Platform.runLater(...).
The only thing I came up with is a default method:
public interface Callback<T> {
void invoke(T param);
default void invokeOnMain(T param){
Platform.runLater(() -> invoke(param));
}
}
And then, I just call result.invokeOnMain(list).
Is there a better approach for patterns like this one?
You can go one step further than the suggestions in the other answers, and abstract Platform.runLater() as an java.util.concurrent.Executor (it is, after all, something that executes Runnables).
So you can do this:
import java.util.concurrent.Executor ;
import java.util.function.Consumer ;
import java.util.function.Supplier ;
public class Invoker {
private final Executor backgroundExecutor ;
private final Executor foregroundExecutor ;
public Invoker(Executor backgroundExecutor, Executor foregroundExecutor) {
this.backgroundExecutor = backgroundExecutor ;
this.foregroundExecutor = foregroundExecutor ;
}
public <T> void invoke(Supplier<? extends T> task, Consumer<? super T> callback) {
backgroundExecutor.execute(() -> {
T result = task.get();
foregroundExecutor.execute(() -> callback.accept(result));
});
}
}
And now your example code becomes:
Invoker invoker = new Invoker(asyncExecutor, Platform::runLater);
// ...
invoker.invoke(folder::getSubFolders, result::invoke);
The nice thing here is you can use the same Invoker class with Swing: just create a
new Invoker(asyncExecutor, SwingUtilities::invokeLater)
[Note: I did not come up with this myself; I saw it in a post on here a few years back. I cannot find that post now to give proper credit, but will edit this if I manage to dig it out. If the person who originally posted this idea sees this, please comment and I will credit you]
It defeats in a some way the default method intention :
Default methods enable you to add new functionality to the interfaces
of your libraries and ensure binary compatibility with code written
for older versions of those interfaces.
Why not put this code in a specific class :
public class PlatformUtil {
public static <T> void invoke(Callback<T> result, T param){
Platform.runLater(() -> result.invoke(param));
}
}
And from the client side, you could also use a static import for PlatformUtil.invoke to reduce further the boiler plate code.
It could give :
import static PlatformUtil.invoke;
...
public void getSubfolders(Folder folder, Callback<FolderList> result){
asyncExecutor.submit(() -> {
FolderList list = folder.get_SubFolders();
invoke(result, list);
});
}
Of course you could do the same thing with an instance method.
After you use the Decorator Pattern, you found that you never need to change the getSubfolders method at all. and then you can write a well defined layer system, when you put the components into its own package, for example:
// v--- move the UiCallback into ui package
package com.projectx.ui;
public class UiCallback<T> implements Callback<T> {
private final Callback<T> target;
private UiCallback(Callback<T> target){
this.target = Objects.requireNonNull(target);
}
public void invoke(T param){
Platform.runLater(() -> target.invoke(param));
}
public static <T> Callback<T> runOnMainThread(Callback<T> source){
return source instanceof UiCallback? source : new UiCallback<>(source);
}
}
Everything is fine, there is only one place you need to change is where you call the getSubfolders, for example:
Callback<T> origin = ...
getSubfolders(folder, runOnMainThread(origin));
If you found that you need to call runOnMainThread many times in your UI module, maybe you lose some domain concepts in your UI layer. you should to extract new domain concept by new classes or interfaces for that things, e.g: FolderExplorer.

Categories

Resources