Java Lambda to Method - java

Given that I know little and nothing about java, exactly like my English,
I have a problem, I have this line of code and I had to delete the lambdas.
return articles (args -> {}, queryDef);
I used Android Studio, (Alt Enter) and it creates me
private com.shopify.buy3.Storefront.BlogQuery.ArticlesArgumentsDefinition GetArticlesArgumentsDefinition () {
return args -> {};
}
always with lambdas.
How can I convert args -> {} in order to eliminate them?
Thank you
EDIT:
public BlogQuery articles(ArticleConnectionQueryDefinition queryDef) {
return articles(args -> {}, queryDef);
}
/**
* List of the blog's articles.
*/
public BlogQuery articles(ArticlesArgumentsDefinition argsDef, ArticleConnectionQueryDefinition queryDef) {
startField("articles");
ArticlesArguments args = new ArticlesArguments(_queryBuilder);
argsDef.define(args);
ArticlesArguments.end(args);
_queryBuilder.append('{');
queryDef.define(new ArticleConnectionQuery(_queryBuilder));
_queryBuilder.append('}');
return this;
}

You could define a conventional implementation of ArticlesArgumentsDefinition, though I don't recommend it. Why do you have to get rid of the lambda?
return articles(new ArticlesArgumentsDefinition() {
#Override
public void define(ArticlesArguments args) { }
});
Here, I've used an anonymous class, which is the closest pre-lambda equivalent to a real lambda, but this could be any kind of class.

You are looking for "Replace lambda with anonymous class" intention available when doing Alt+Enter on -> symbol. It should replace your lambda with something like this:
return articles(new BlogQuery.ArticlesArgumentsDefinition() {
#Override
public void define(ArticlesArguments args) {
// body of lambda
}
});
I think you should be able to do Alt+Enter -> Replace lambda with anonymous class -> Fix all... to do it in one go.

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 to use functional interface returning void?

I have this construction:
if (Objects.isNull(user.getMartialStatus())) {
user.setMartialStatus(MartialStatus.MARRIED);
}
I have many of them, & I want to optimize code using functional interface.
Okay. I write something like this:
public static <T> void processIfNull(T o, Supplier<Void> s) {
if (Objects.isNull(o)) {
s.get();
}
}
Then, I wait that this code shall work:
processIfNull(user.getMartialStatus(), () -> user.setMartialStatus(MartialStatus.MARRIED));
But IDEA write:
void is not compatible with Void
Please, tell me, what to do.
As the error explains Void is a class which is not equivalent to void. Supplier<Void> expects to return Void like Supplier<String> will expect String object to return.
So your functional interface should be like below.
It has a void apply() which matches the signature of () -> ...
#FunctionalInterface
public interface ActionIfNotNull {
void apply();
}
However when you search for an inbuild functional interface, you can come up with Runnable as Jon Skeet suggested.
Solution
public static <T> void processIfNull(T o, Runnable s) { // instead of you Runnable can use your own functional interface like ActionIfNotNull
if (Objects.isNull(o)) {
s.run();
}
}
As of Java 9 Optional has the ifPresentOrElse method, which could be used for this.
Optional
.ofNullable(user.getMartialStatus())
.ifPresentOrElse(o -> {}, () -> user.setMartialStatus(MartialStatus.MARRIED););
You could also replace the o -> {} by some NOOP Consumer if you like, like this:
private static final Consumer<Object> NOOP = o -> {};
...
Optional
.ofNullable(user.getMartialStatus())
.ifPresentOrElse(NOOP, () -> user.setMartialStatus(MartialStatus.MARRIED););
Anyway, I think the solution Trine came up with, is preferable, because it makes it much clearer, what's going on.

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.

Categories

Resources