Inverse of Supplier<T> in Guava - java

I'm looking for the inverse of Supplier<T> in Guava. I hoped it would be called Consumer – nope – or Sink – exists, but is for primitive values.
Is it hidden somewhere and I'm missing it?
I'd like to see it for the same kinds of reasons that Supplier is useful. Admittedly, uses are less common, but many of the static methods of Suppliers, for example, would apply in an analogous way, and it would be useful to express in one line things like "send this supplier every value in this iterable".
In the meantime, Predicate and Function<T,Void> are ugly workarounds.

Your alternatives are:
Java 8 introduces a Consumer interface which you can compose.
Xtend's standard library contains Procedures.
Scala has Function*; if a function's return type is Unit, it is considered a side effect.
In all of these languages, you can use functional interfaces conveniently, so you could also use e.g. Functional Java's Effect.
Otherwise, you better rely on existing language constructs for performing side effects, e.g. the built-in for loop. Java < 8 inflicts tremendous syntactic overhead when using lambdas. See this question and this discussion.

You can use a Function and set the second Argument to java.lang.Void this Function can only return null.

You have already found the answer. If you just want to visit, you can use filter with a predicate that always returns true; if you are super defensive you can use any predicate and use an or function with an alwaysTrue in the filter itself; just add the or at the end to avoid shortcircuiting.
The problem is that even though I agree that conceptually Predicate and Consumer are different since a Predicate should be as stateless as possible and not have side effects while a consumer is only about the side effects, in practice the only syntactic difference is that one returns a boolean (that can be ignored) and the other void. If Guava had a Consumer, it would need to either duplicate several of the methods that take a Predicate to also take a Consumer or have Consumer inherit from Predicate.

Related

List forEach with method reference explanation

I have been learning java for past few months and just started to get into lambda functions. I recently switched my IDE and noticed a warning saying "Can be replaced with method reference" on codes like this.
List<Integer> intList = new ArrayList<>();
intList.add(1);
intList.add(2);
intList.add(3);
intList.forEach(num -> doSomething(num));
voiddoSomething(int num) {
System.out.println("Number is: " + num);
}
After some digging, I realized that instead of the line
intList.forEach(num -> doSomething(num));
I can just use
intList.forEach(this::doSomething);
This is just amazing. A few days ago I did not even knew about lambdas and was using for loops to do operations like this. Now I replaced my for loops with lambdas and even better, I can replace my lambdas with method references. The problem is that I don't really understand how all this works internally. Can anyone please explain or provide a good resource explaining how the doSomething function is called and the argument is passed to it when we use method reference?
The double-colon operator is simply a convenience operator for doing the same thing that your lambda is doing. Check out this page for more details: https://javapapers.com/core-java/java-method-reference/
The double colon is simply syntactic sugar for defining a lambda expression whose parameters and return type are the same as an existing function. It was created to to allow lambdas to more easily be added with existing codebases.
Calling the forEach method of a List<Integer> object takes as its parameter any object implementing the Consumer functional interface. Your lambda num -> doSomething(num) itself happens to fulfill the formal requirements of this interface.
Thus, you can use the double colon as syntactic sugar for that lambda expression.
In general, if you have an object obj with method func, which accepts parameters params... then writing obj::func is equivalent to the lambda (params...) -> obj.func(params...).
In your case, o is this (the current object), which has a method doSomething(), which takes an integer parameter, thus, this::doSomething is equivalent to num -> doSomething(num).
Given you've mentioned that it's only until recently you started getting into functional programming I'd like to keep things as simple and straightforward as possible, but note that with just the little code you've provided, we could derive a lot both from the high-level view of things as well the low-level view.
Can anyone please explain or provide a good resource explaining how
the doSomething function is called and the argument is passed to it
when we use method reference?
how the doSomething function is called is left to the library (internal iteration) regardless of whether we use a method reference or a lambda expression, so essentially we specify the what not the how meaning we provide to the forEach method a behaviour (a function) that we want to execute for each element of the source intList and not necessarily how it should go about its work.
This is then left to the library to apply (execute) the specified function of doSomething for each element of the source intList.
Method references can be seen as a shorthand for lambdas calling only a specific method. The benefit here is that by referring to a specific method name explicitly, your code gains better readability, therefore, making it easier to read and follow and in most cases reading code with method references reads as the problem statement which is a good thing.
It's also important to know that not any given function can be passed to the forEach terminal operation as every method that accepts a behaviour has a restriction on the type of function allowed. This is accomplished with the use of functional interfaces in the java.util.function package.
Lastly but not least, in terms of refactoring it's not always possible to use method references nor is it always better to use lambdas expressions over code that we used prior to Java-8. However, as you go on with your journey of learning the Java-8 features, a few tips to better your code are to try:
Refactoring anonymous classes to lambda expressions
Refactoring lambda expressions to method references
Refactoring imperative-style data processing to streams

Functional programming idiom for applying a series of void functions to a single value

Given a value foo and a Stream of Consumer<Foo> void functions, what's the most concise way to apply each function to the value? Right now I have
consumers.forEach(c -> c.accept(foo));
which isn't terrible, but I suspect there might be some way to turn this inside out and do it with just method references (no explicit lambda). Possibly something with a singleton list and zip()?
I'd be happy with a straight Java 8 answer, or Vavr, or Scala.
(Note that this is not a fold, or at least not the usual foldLeft/foldRight application; if there were return values, I'd be discarding them, not iterating on them.)
I think the real concern here is that methods which return void are a code smell. Why couldn't they return something useful, or at least carry out their side-effect and then return the original value, which allows for better chaining. I think that would be a preferable approach, but short of that, I think the forEach approach is ok.
You could reduce your consumers by means of the Consumer.andThen method and then apply the resulting consumer to the foo argument:
consumers.reduce(Consumer::andThen).ifPresent(c -> c.accept(foo));
But there's no difference between this approach and yours, and yours' is shorter.
In Scala you should be able to do
consumers.foreach(_.accept(foo));

Predicates vs if statements

I have seen in some projects that people use Predicates instead of pure if statements, as illustrated with a simple example below:
int i = 5;
// Option 1
if (i == 5) {
// Do something
System.out.println("if statement");
}
// Option 2
Predicate<Integer> predicate = integer -> integer == 5;
if (predicate.test(i)) {
// Do something
System.out.println("predicate");
}
What's the point of preferring Predicates over if statements?
Using a predicate makes your code more flexible.
Instead of writing a condition that always checks if i == 5, you can write a condition that evaluates a Predicate, which allows you to pass different Predicates implementing different conditions.
For example, the Predicate can be passed as an argument to a method :
public void someMethod (Predicate<Integer> predicate) {
if(predicate.test(i)) {
// do something
System.out.println("predicate");
}
...
}
This is how the filter method of Stream works.
For the exact example that you provided, using a Predicate is a big over-kill. The compiler and then the runtime will create:
a method (de-sugared predicate)
a .class that will implement java.util.Predicate
an instance of the class created at 2
all this versus a simple if statement.
And all this for a stateless Predicate. If your predicate is statefull, like:
Predicate<Integer> p = (Integer j) -> this.isJGood(j); // you are capturing "this"
then every time you will use this Predicate, a new instance will be created (at least under the current JVM).
The only viable option IMO to create such a Predicate is, of course, to re-use it in multiple places (like passing as arguments to methods).
Using if statements is the best (read: most performant) way to check binary conditions.
The switch statement may be faster for more complex situations.
A Predicate are a special form of Function. In fact the java language architect work on a way to allow generic primitive types. This will make Predicate<T> roughly equivalent to Function<T, boolean> (modulo the test vs apply method name).
If a function (resp. method) takes one or more functions as argument(s), we call it higher-order function. We say that we are passing behaviour to a function. This allows us to create powerful APIs.
String result = Match(arg).of(
Case(isIn("-h", "--help"), help()),
Case(isIn("-v", "--version"), version()),
Case($(), cmd -> "unknown command: " + cmd)
);
This example is taken from Javaslang, a library for object-functional programming in Java 8+.
Disclaimer: I'm the creator of Javaslang.
Thi is an old question, but I'll give it a try, since I am battling with it myself...
In my attempt to excuse my own usage of predicates I have made a self-rule.
I believe Predicates are useful where the "logic point" - is NOT the: leaf | corner | the end - of a: graph | tree | straight line, which would make the logic point effectively a "logic joint".
By it being a joint (aka node) it has a state, a re-usable and mutable state, that serves as a means towards an end.
In a stream, where the data is supposed to traverse a path, predicates are useful since they grant a degree of access while keeping the integrity of the stream, this is why the best predicates IMO are only method references minimizing side effects.
Even though the most common form of Predicate is newObject.equal(old), which is in itself a BiPredicate, but CAN be used with a single Predicate with side effect lambda -> lambda.equal(localCache) (so this may be an exception to the Only Method References rule).
IF, the logic serves as the output/exit point towards a different architectural design, or component, or a code that is not written by you, or even if it is written by you, one that differs on its functionality, then an if-else is my way to go.
Another benefit of predicates in the case of reactive programming is that multiple subscribers can make use of the same defined logic gate.
But if the end point of a publisher will be a single lone subscriber (which would be a case similar to your example if I'm reaching), then the logic is better done with an if-else.

How to decide between lambda iteration and normal loop?

Since he introduction of Java 8 I got really hooked to lambdas and started using them whenever possible, mostly to start getting accustomed to them. One of the most common usage is when we want to iterate and act upon a collection of objects in which case I either resort to forEach or stream(). I rarely write the old for(T t : Ts) loop and I almost forgot about the for(int i = 0.....).
However, we were discussing this with my supervisor the other day and he told me that lambdas aren't always the best choice and can sometimes hinder performance. From a lecture I had seen on this new feature I got the feeling that lambda iterations are always fully optimized by the compiler and will (always?) be better than bare iterations, but he begs to differ. Is this true? If yes how do I distinguish between the best solution in each scenario?
P.S: I'm not talking about cases where it is recommended to apply parallelStream. Obviously those will be faster.
Performance depends on so many factors, that it’s hard to predict. Normally, we would say, if your supervisor claims that there was a problem with performance, your supervisor is in charge of explaining what problem.
One thing someone might be afraid of, is that behind the scenes, a class is generated for each lambda creation site (with the current implementation), so if the code in question is executed only once, this might be considered a waste of resources. This harmonizes with the fact that lambda expressions have a higher initialization overhead as the ordinary imperative code (we are not comparing to inner classes here), so inside class initializers, which only run once, you might consider avoiding it. This is also in line with the fact, that you should never use parallel streams in class initializers, so this potential advantage isn’t available here anyway.
For ordinary, frequently executed code that is likely to be optimized by the JVM, these problems do not arise. As you supposed correctly, classes generated for lambda expressions get the same treatment (optimizations) as other classes. At these places, calling forEach on collections bears the potential of being more efficient than a for loop.
The temporary object instances created for an Iterator or the lambda expression are negligible, however, it might be worth noting that a foreach loop will always create an Iterator instance whereas lambda expression do not always do. While the default implementation of Iterable.forEach will create an Iterator as well, some of the most often used collections take the opportunity to provide a specialized implementation, most notably ArrayList.
The ArrayList’s forEach is basically a for loop over an array, without any Iterator. It will then invoke the accept method of the Consumer, which will be a generated class containing a trivial delegation to the synthetic method containing the code of you lambda expression. To optimize the entire loop, the horizon of the optimizer has to span the ArrayList’s loop over an array (a common idiom recognizable for an optimizer), the synthetic accept method containing a trivial delegation and the method containing your actual code.
In contrast, when iterating over the same list using a foreach loop, an Iterator implementation is created containing the ArrayList iteration logic, spread over two methods, hasNext() and next() and instance variables of the Iterator. The loop will repeatedly invoke the hasNext() method to check the end condition (index<size) and next() which will recheck the condition before returning the element, as there is no guaranty that the caller does properly invoke hasNext() before next(). Of course, an optimizer is capable of removing this duplication, but that requires more effort than not having it in the first place. So to get the same performance of the forEach method, the optimizer’s horizon has to span your loop code, the nontrivial hasNext() implementation and the nontrivial next() implementation.
Similar things may apply to other collections having a specialized forEach implementation as well. This also applies to Stream operations, if the source provides a specialized Spliterator implementation, which does not spread the iteration logic over two methods like an Iterator.
So if you want to discuss the technical aspects of foreach vs. forEach(…), you may use these information.
But as said, these aspects describe only potential performance aspects as the work of the optimizer and other runtime environmental aspects may change the outcome completely. I think, as a rule of thumb, the smaller the loop body/action is, the more appropriate is the forEach method. This harmonizes perfectly with the guideline of avoiding overly long lambda expressions anyway.
It depends on specific implementation.
In general forEach method and foreach loop over Iterator usually have pretty similar performance as they use similar level of abstraction. stream() is usually slower (often by 50-70%) as it adds another level that provides access to the underlying collection.
The advantages of stream() generally are the possible parallelism and easy chaining of the operations with lot of reusable ones provided by JDK.

Converting Consumers to Functions

Many lambdas for the Function interface take the form
t -> {
// do something to t
return t;
}
I do this so often that I have written a method for it like this.
static <T> Function<T, T> consumeThenReturn(Consumer<T> consumer) {
return t -> {
consumer.accept(t);
return t;
};
}
This enables me to do really nice things like this:
IntStream.rangeClosed('A', 'Z')
.mapToObj(a -> (char) a)
.collect(Collectors.collectingAndThen(Collectors.toList(), consumeThenReturn(Collections::shuffle)))
.forEach(System.out::print);
Is there another way to do conversions like this without relying on my own method? Is there anything in the new APIs I have missed that makes my method redundant?
There are many potentially useful methods that could be added to the Function, Consumer and Supplier interfaces. You give a good example (converting a Consumer to a Function) but there are many other potential conversions or utilities that could be added. For example, using a Function as Consumer (by ignoring the return value) or as a Supplier (by providing an input value). Or converting a BiFunction to a Function by supplying either value. All of these can, of course, be done manually in code or provided via utility functions as you've shown but it would arguably be valuable to have standardised mechanisms in the API, as exist in many other languages.
It is speculation on my part, but I would guess this reflects the language designers' desire to leave the API as clean as possible. However I'm intrigued by the contrast (as an example) to the very rich set of Comparator utilities provided by the language to reverse orders, compare by several criteria, deal with null values etc. These also could easily have been left to the user but have been supplied by the API. I'd be interested to hear from one of the language designers why the approaches to these interfaces seems so inconsistent.
Apache commons collections 4.x has what you're looking for, I think. Its equivalents for Function and Consumer are Transformer and Closure, respectively, and it provides a way to compose them using ClosureTransformer
It is trivial to convert between equivalent functional types by invoking the SAM of one and assigning it to the other. Putting it all together, you can end up with a Java 8 Function in this manner:
Consumer<String> c = System.out::println;
Function<String,String> f = ClosureTransformer.closureTransformer(c::accept)::transform;
c::accept converts the Java 8 Consumer to an equivalent Apache Commons 4 Closure, and the final ::transform converts the Apache Commons 4 Transformer to an equivalent Java 8 Function.

Categories

Resources