How to use functional interface returning void? - java

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.

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.

Java Lambda to Method

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.

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.

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.

Lambda Expressions in Java8

import java.util.concurrent.Callable;
public class AdvancedLambda {
static void invoke(Runnable r){
r.run();
}
static Object invoke(Callable c) throws Exception {
return c.call();
}
public static void main(String[] args) throws Exception {
String s = (String) invoke(() -> true);
System.out.println(s);
}
}
Can anyone help me understand this? I was under the impression that we can only use lamba expressions in Java 8 only when we implement an interface and override its methods (replacing Anonymous classes by Lambda expressions).
Also in which situation will the method invoke(Runnable r) be called?
In the following line
String s = (String) invoke(() -> true);
It is actually invoke(Callable) that is getting called. The reason is:
() -> true is a lambda expression that has zero formal parameter and return a result.
Such a signature (zero parameter, single result) is compatible with the functional method call() of the Callable interface. Note that the interface does not need to have the #FunctionalInterface annotation, it just needs to have a single abstract method.
If you want to invoke invoke(Runnable) instead, you will need to create a lambda that is compatible with a functional method that takes zero parameter and returns no result (i.e. conforms with the signature of run()). Something like this:
invoke(() -> System.out.println("foo"));
Which just prints foo when ran.
A lambda expression supplies an implementation for a functional interface. This is what your code snippet does.
Your call to invoke passes a lambda expression with no arguments that returns a value (a boolean in your case). Therefore it matches Object invoke(Callable c), and not void invoke(Runnable r) (since a Callable's call method has a return value while a Runnable's run method doesn't return anything).
invoke(() -> {System.out.println("something");});
will call void invoke(Runnable r), since in this case the lambda expression has no return type.
only when we Implement a interface and override its methods
That's, more or less, what you do here. Not methods, but just one method: call(). This () -> true part is your implementation of Callable#call().
In other words, this line:
String s = (String) invoke(() -> true);
would be totally equivalent with this one:
String s = (String) invoke(new Callable() {
#Override
public Object call() throws Exception {
return true;
}
});
LambdaParameters -> LambdaBody
The arrow operator (->) for defining lambda functions
Lambda :can only be used to execute background tasks (here compiler then figures out)
Expressions : are return a value of some kind
Lambda expression is another way of writing an instance of anonymous class, to make an instance of anonymous class easier to write. In JVM, it will not occupy much memory as comparing with normal java object creation with new(executing static variables, static blocks, loading classes from whole hierarchy ).
Lambda expression syntax:
(params) -> expression to implement a #FunctionalInterface
In your test case: String s = (String) invoke(() -> true); the expression has return type true with no argument. So the Runnable FunctionalInterface does not match with lambda expression because it has void run() attribute. It matches with Callable FuncationalInterface using
V call().
How lambda expressions work under the hood?
It might look like the lambda expressions are just the syntax sugar for anonymous inner classes, but there is much more elegant approach. The simplest explanation is: the lambda expression is represented by a new method, and it is invoked at run-time using invokedynamic.
Source Code:
class LambdaExample {
public void abc() {
Runnable r = () -> {
System.out.println("hello");
}
r.run();
}
}
Bytecode equivalent:
class LambdaExample {
public void abc() {
Runnable r = <lambda$1 as Runnable instance>;
r.run();
}
static void lambda$1() {
System.out.println("hello");
}
}
Inside the JVM, there is a lambda factory that creates an instance of the functional interface (e.g. Runnable) from the generated lambda method (e.g. lambda$1).
Lambda expressions are great, and there's even more great stuff in Java 8...
Take a look at below example.
import javafx.beans.DefaultProperty;
import jdk.nashorn.internal.codegen.CompilerConstants;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
* Created by KUMAJYE on 13/09/2016.
*/
public class ThreadMonitor {
private static int noOfThreads = 0;
public static void main(String[] args) {
ThreadModel threadModel;
noOfThreads = Integer.parseInt(args[0]);
if (noOfThreads > 0) {
threadModel = getThreadingModelForCallsInCallingThread();
} else {
threadModel = getAsynchThreadingModel();
}
}
public static ThreadModel getThreadingModelForCallsInCallingThread() {
ExecutorService executor = Executors.newFixedThreadPool(noOfThreads);
return (r) -> executor.submit(r);
}
public static ThreadModel getAsynchThreadingModel() {
// do execution on same Thread or separate Thread.
// or
// r.run();
return (r) -> new Thread(r).start();
}
interface ThreadModel {
void invoke(Runnable r);
}
}

Categories

Resources