Why to use andThen in Consumer functional interface? - java-8

I want to perform one task one after another. We can do it in two ways.
First way is :
List<String> list = Arrays.asList("Name1","Name2","Name3");
list.forEach((obj)->{
System.out.println(obj); //task1
System.out.println(obj.length()); //task2
});
Or we can do in this way as well :
List<String> list = Arrays.asList("Name1","Name2","Name3");
Consumer<String> c1 = (obj)-> System.out.println(obj); //task1
Consumer<String> c2 = (obj)-> System.out.println(obj.length()); //task2
list.forEach(c1.andThen(c2));
In both the cases we get the same result, so why do we use andThen in Consumer functional interface? Is there any advantage in using it?

One of the idea behind functions (Function<A, B>) is that they are composable,
eg. g(f(x)) which is equivalent to f.andThen(g).apply(x) in java.
Defining one function or multiple functions depends on responsibility you want to give for each function.
For example you can have separate "function for incrementing a number" and "function for creating square of a number" that way you can re-use them when needed.
Function<Integer, Integer> f = a -> a + 1;
Function<Integer, Integer> g = a -> a * a;
var incrementAndSquare = f.andThen(g).apply(2); //9
Function<Integer, Integer> h = a -> a - 1;
var decrementAndSquare = h.andThen(g).apply(5); //16
Note: Consumer<A> in java is also a function Function<A, void> that returns void.
In your case if its just println maybe one function should be enough unless you need same function somewhere else.
If you are doing two "separate tasks", you might want to define separate functions. That makes the responsibility clearer, provides composibility, easy to test functions individually.

Related

How to return the count, while using nested foreach loops in the stream

I am using java8 streams to iterate two lists, In that one list contains some custom objects and another contains string.
With this, I have to call a method by passing custom object and sting as a input and then I have to get the count.
This is what I tried:
public int returnCode() {
/*int count = 0;
* list.forEach(x -> {
list2.forEach(p -> {
count+ = myDao.begin(conn, x.getCode(), p);
});
return count;
});*/
}
compiler is giving an error that count should be final.
Can anyone, give me how to do this in a better way.
What you're attempting to do is not possible as local variables accessed from a lambda must be final or effectively final i.e. any variable whose value does not change.
You're attempting to change the value of count in the lambda passed to the forEach hence the compilation error.
To replicate your exact code using the stream API, it would be:
int count = list.stream()
.limit(1)
.flatMapToInt(x -> list2.stream().mapToInt(p -> myDao.begin(conn, x.getCode(), p)))
.sum();
However, if you want to iterate over the entire sequence in list and not just the first then you can proceed with the following:
int count = list.stream()
.flatMapToInt(x -> list2.stream().mapToInt(p -> myDao.begin(conn, x.getCode(), p)))
.sum();
Lambdas mainly substitutes anonymous inner classes. Inside an anonymous inner class you can access only final local variables. Hence the same holds true with lambda expressions. Local variable is copied when JVM creates a lambda instance, hence it is counter intuitive to allow any update to them. So declaring the variable as final would solve the issue. But if you make it final you won't be able to do this, leading to another pitfall.
count+ = myDao.begin(conn, x.getCode(), p);
So your solution is not good and does not comply with lambda. So this will be a one way of doing it.
final int count = customObjects.stream()
.mapToInt(co -> strings.stream().mapToInt(s -> myDao.begin(conn, co.getCode(), s)).sum())
.sum();

How to get that the limit exceeded when I use limit() on a range of items from stream using Java 8 lambda?

How should I know without using another condition to compare the map.size() with limitValue, that the limit was exceeding when my stream iterated?
Here,
for limitValue = 3, it should return false.
for limitValue = 4, it should return true.
I can not use an outside int field as it must be final to be used inside lambda.
import java.util.*;
import java.util.stream.*;
public class Test {
public static void main(String[] args) throws Exception {
Map<Integer, String> map = new HashMap<>();
map.put(1, "foo");
map.put(2, "bar");
map.put(3, "baz");
int limitValue = 3;
String result = map.entrySet()
.stream()
.limit(limitValue)
.map(entry -> entry.getKey() + " - " + entry.getValue())
.collect(Collectors.joining(", "));
System.out.println(result);
}
}
I can not use an outside int field as it must be final to be used
inside lambda.
Yes, this is because, within a lambda expression, you can only reference local variables whose value doesn’t change (in java).
This is a good thing in a way as mutating a variable(s) inside a lambda is not thread safe when executing in parallel.
So, the system is helping you prevent such scenarios at compile time by allowing only final or effectively final variables to be used in lambdas.
Note, this restriction only holds for local variables.
Anyhow, my advice is not to mutate variables that are not solely contained within a given function itself as it introduces a side-effect and side-effects in behavioral parameters to stream operations are, in general, discouraged.
Keep things simple and proceed with the below approach.
boolean exceeded = limitValue > map.size();

JAVA 8 Extract predicates as fields or methods?

What is the cleaner way of extracting predicates which will have multiple uses. Methods or Class fields?
The two examples:
1.Class Field
void someMethod() {
IntStream.range(1, 100)
.filter(isOverFifty)
.forEach(System.out::println);
}
private IntPredicate isOverFifty = number -> number > 50;
2.Method
void someMethod() {
IntStream.range(1, 100)
.filter(isOverFifty())
.forEach(System.out::println);
}
private IntPredicate isOverFifty() {
return number -> number > 50;
}
For me, the field way looks a little bit nicer, but is this the right way? I have my doubts.
Generally you cache things that are expensive to create and these stateless lambdas are not. A stateless lambda will have a single instance created for the entire pipeline (under the current implementation). The first invocation is the most expensive one - the underlying Predicate implementation class will be created and linked; but this happens only once for both stateless and stateful lambdas.
A stateful lambda will use a different instance for each element and it might make sense to cache those, but your example is stateless, so I would not.
If you still want that (for reading purposes I assume), I would do it in a class Predicates let's assume. It would be re-usable across different classes as well, something like this:
public final class Predicates {
private Predicates(){
}
public static IntPredicate isOverFifty() {
return number -> number > 50;
}
}
You should also notice that the usage of Predicates.isOverFifty inside a Stream and x -> x > 50 while semantically the same, will have different memory usages.
In the first case, only a single instance (and class) will be created and served to all clients; while the second (x -> x > 50) will create not only a different instance, but also a different class for each of it's clients (think the same expression used in different places inside your application). This happens because the linkage happens per CallSite - and in the second case the CallSite is always different.
But that is something you should not rely on (and probably even consider) - these Objects and classes are fast to build and fast to remove by the GC - whatever fits your needs - use that.
To answer, it's better If you expand those lambda expressions for old fashioned Java. You can see now, these are two ways we used in our codes. So, the answer is, it all depends how you write a particular code segment.
private IntPredicate isOverFifty = new IntPredicate<Integer>(){
public void test(number){
return number > 50;
}
};
private IntPredicate isOverFifty() {
return new IntPredicate<Integer>(){
public void test(number){
return number > 50;
}
};
}
1) For field case you will have always allocated predicate for each new your object. Not a big deal if you have a few instances, likes, service. But if this is a value object which can be N, this is not good solution. Also keep in mind that someMethod() may not be called at all. One of possible solution is to make predicate as static field.
2) For method case you will create the predicate once every time for someMethod() call. After GC will discard it.

Java 8 JPA Repository Stream produce two (or more) results?

I have a Java 8 stream being returned by a Spring Data JPA Repository. I don't think my usecase is all that unusual, there are two (actually 3 in my case), collections off of the resulting stream that I would like collected.
Set<Long> ids = // initialized
try (Stream<SomeDatabaseEntity> someDatabaseEntityStream =
someDatabaseEntityRepository.findSomeDatabaseEntitiesStream(ids)) {
Set<Long> theAlphaComponentIds = someDatabaseEntityStream
.map(v -> v.getAlphaComponentId())
.collect(Collectors.toSet());
// operations on 'theAlphaComponentIds' here
}
I need to pull out the 'Beta' objects and do some work on those too. So I think I had to repeat the code, which seems completely wrong:
try (Stream<SomeDatabaseEntity> someDatabaseEntityStream =
someDatabaseEntityRepository.findSomeDatabaseEntitiesStream(ids)) {
Set<BetaComponent> theBetaComponents = someDatabaseEntityStream
.map(v -> v.getBetaComponent())
.collect(Collectors.toSet());
// operations on 'theBetaComponents' here
}
These two code blocks occur serially in the processing. Is there clean way to get both Sets from processing the Stream only once? Note: I do not want some kludgy solution that makes up a wrapper class for the Alpha's and Beta's as they don't really belong together.
You can always refactor code by putting the common parts into a method and turning the uncommon parts into parameters. E.g.
public <T> Set<T> getAll(Set<Long> ids, Function<SomeDatabaseEntity, T> f)
{
try(Stream<SomeDatabaseEntity> someDatabaseEntityStream =
someDatabaseEntityRepository.findSomeDatabaseEntitiesStream(ids)) {
return someDatabaseEntityStream.map(f).collect(Collectors.toSet());
}
}
usable via
Set<Long> theAlphaComponentIds = getAll(ids, v -> v.getAlphaComponentId());
// operations on 'theAlphaComponentIds' here
and
Set<BetaComponent> theBetaComponents = getAll(ids, v -> v.getBetaComponent());
// operations on 'theBetaComponents' here
Note that this pulls the “operations on … here” parts out of the try block, which is a good thing, as it implies that the associated resources are released earlier. This requires that BetaComponent can be processed independently of the Stream’s underlying resources (otherwise, you shouldn’t collect it into a Set anyway). For the Longs, we know for sure that they can be processed independently.
Of course, you could process the result out of the try block even without the moving the common code into a method. Whether the original code bears a duplication that requires this refactoring, is debatable. Actually, the operation consists a single statement within a try block that looks big only due to the verbose identifiers. Ask yourself, whether you would still deem the refactoring necessary, if the code looked like
Set<Long> alphaIDs, ids = // initialized
try(Stream<SomeDatabaseEntity> s = repo.findSomeDatabaseEntitiesStream(ids)) {
alphaIDs = s.map(v -> v.getAlphaComponentId()).collect(Collectors.toSet());
}
// operations on 'theAlphaComponentIds' here
Well, different developers may come to different conclusions…
If you want to reduce the number of repository queries, you can simply store the result of the query:
List<SomeDatabaseEntity> entities;
try(Stream<SomeDatabaseEntity> someDatabaseEntityStream =
someDatabaseEntityRepository.findSomeDatabaseEntitiesStream(ids)) {
entities=someDatabaseEntityStream.collect(Collectors.toList());
}
Set<Long> theAlphaComponentIds = entities.stream()
.map(v -> v.getAlphaComponentId()).collect(Collectors.toSet());
// operations on 'theAlphaComponentIds' here
Set<BetaComponent> theBetaComponents = entities.stream()
.map(v -> v.getBetaComponent()).collect(Collectors.toSet());
// operations on 'theBetaComponents' here

What are nested functions? What are they for?

I've never used nested functions, but have seen references to them in several languages (as well as nested classes, which I assume are related).
What is a nested function?
Why?!?
What can you do with a nested function that you cannot do any other way?
What can you do with a nested function this is difficult or inelegant without nested functions?
I assume nested functions are simply an artifact of treating everything as an object, and if objects can contain other objects then it follows.
Do nested functions have scope (in general, I suppose languages differ on this) just as variables inside a function have scope?
Please add the language you are referencing if you're not certain that your answer is language agnostic.
-Adam
One popular use of nested functions is closures. In a lexically scoped language with first-class functions it's possible to use functions to store data. A simple example in Scheme is a counter:
(define (make-counter)
(let ((count 0)) ; used to store the count
(define (counter) ; this is the counter we're creating
(set! count (+ count 1)) ; increment the count
count) ; return the new count
counter)) ; return the new counter function
(define mycounter (make-counter)) ; create a counter called mycounter
(mycounter) ; returns 1
(mycounter) ; returns 2
In this example, we nest the function counter inside the function make-counter, and by returning this internal function we are able to access the data available to counter when it was defined. This information is private to this instance of mycounter - if we were to create another counter, it would use a different spot to store the internal count. Continuing from the previous example:
(define mycounter2 (make-counter))
(mycounter2) ; returns 1
(mycounter) ; returns 3
It's useful for recursion when there is only 1 method that will ever call it
string[] GetFiles(string path)
{
void NestedGetFiles(string path, List<string> result)
{
result.AddRange( files in the current path);
foreach(string subPath in FoldersInTheCurrentPath)
NestedGetFiles(subPath, result);
}
List<string> result = new List<string>();
NestedGetFiles(path, result);
return result.ToArray();
}
The above code is completely made up but is based on C# to give the idea of what I mean. The only method that can call NestedGetFiles is the GetFiles method.
Nested functions allow you to encapsulate code that is only relevant to the inner workings of one function within that function, while still allowing you to separate that code out for readability or generalization. In some implementations, they also allow access to outer scope. In D:
int doStuff() {
int result;
void cleanUpReturn() {
myResource1.release();
myResource2.release();
return result * 2 + 1;
}
auto myResource1 = getSomeResource();
auto myResource2 = getSomeOtherResource();
if(someCondition) {
return cleanUpReturn();
} else {
doSomeOtherStuff();
return cleanUpReturn();
}
}
Of course, in this case this could also be handled with RAII, but it's just a simple example.
A nested function is simply a function defined within the body of another function. Why? About the only reason I could think of off the top of my head is a helper or utility function.
This is a contrived example but bear with me. Let's say you had a function that had to act on the results two queries and fill an object with values from one of the queries. You could do something like the following.
function process(qryResult q1, qryResult q2) {
object o;
if (q1.someprop == "useme") {
o.prop1 = q1.prop1;
o.prop2 = q1.prop2;
o.prop3 = q1.prop3;
} else if (q2.someprop == "useme") {
o.prop1 = q2.prop1;
o.prop2 = q2.prop2;
o.prop3 = q2.prop3;
}
return o;
}
If you had 20 properties, you're duplicating the code to set the object over and over leading to a huge function. You could add a simple nested function to do the copy of the properties from the query to the object. Like this:
function process(qryResult q1, qryResult q2) {
object o;
if (q1.someprop == "useme") {
fillObject(o,q1);
} else if (q2.someprop == "useme") {
fillObject(o,q2);
}
return o;
function fillObject(object o, qryResult q) {
o.prop1 = q.prop1;
o.prop2 = q.prop2;
o.prop3 = q.prop3;
}
}
It keeps things a little cleaner. Does it have to be a nested function? No, but you may want to do it this way if the process function is the only one that would have to do this copy.
(C#) :
I use that to simplify the Object Browser view, and to structure my classes better.
As class Wheel nested in Truck class.
Don't forget this detail :
"Nested types can access private and protected members of the containing type, including any inherited private or protected members."
They can also be useful if you need to pass a function to another function as an argument. They can also be useful for making factory functions for factory functions (in Python):
>>> def GetIntMaker(x):
... def GetInt():
... return x
... return GetInt
...
>>> GetInt = GetIntMaker(1)
>>> GetInt()
1
A nested function is just a function inside another function.
Yes, it is a result of everything being an object. Since you can have variables only visible in the function's scope and variables can point to functions you can have a function that is referenced by a local variable.
I don't think there is anything that you can do with a nested function that you absolutely couldn't do without. A lot of the times it makes sense, though. Namely, whenever a function is a "sub-function" of some other function.
A common use-case for me is when a function performs a lot of complicated logic but what the function computes/returns is easy to abstract for all the cases dictated by the logic.

Resources