Lambda's and Functional Interfaces
Java 8 is a major improvement and has rich set of features since Java5 . Main draw back with java language was it lacked functional style of programming . Java8 Fixed this , following set of examples to lambda's and other features introduced in java8 .
Lambda expressions are basically anonymous methods , Java can now do functional composition in addition to object composition .
Example of Imperative style
public static void printArray(List arrtoprint)
{
for( int i =0; i< arrtoprint.size(); i++)
{
System.out.println(arrtoprint.get(i));
}
}
public static void printArrayJava5(List arrtoprint)
{
for( String s:arrtoprint)
{
System.out.println(s);
}
}
{
for( int i =0; i< arrtoprint.size(); i++)
{
System.out.println(arrtoprint.get(i));
}
}
public static void printArrayJava5(List
{
for( String s:arrtoprint)
{
System.out.println(s);
}
}
both use external iterators , and boundary conditions , algorithm of looping are all controlled by the code.
Example of Declarative ( functional) Style
Implementation uses internal iterators
public static void printArrayJava8(List arrtoprint)
{
arrtoprint.forEach(System.out::println);
}
lot of things inferred in the above implementation
Descriptive syntax to show print element for each string element in arraylist
arrtoprint.forEach((String e)->System.out.println(e));
Can be shortened to this format , print the element in the arraylist
arrtoprint.forEach(System.out.println(e));
Can be further shortened to this .There is only one element to print , so not even have to mention that
{
arrtoprint.forEach(System.out::println);
}
lot of things inferred in the above implementation
Descriptive syntax to show print element for each string element in arraylist
arrtoprint.forEach((String e)->System.out.println(e));
Can be shortened to this format , print the element in the arraylist
arrtoprint.forEach(System.out.println(e));
Can be further shortened to this .There is only one element to print , so not even have to mention that
arrtoprint.forEach(System.out::println);
Why this is better
Declarative style , values go through mutation - constantly changed
Imperative Style , No mutation - can be parallelized easily
Remove the mechanics - e.g looping can be sequential , or be concurrent or lazy
Implementation done through java interface Consumer
values.forEach( new Consumer() {
public accept(Interger value)
{
System.out.println(value);
}
});
arrtosort.sort((e1,e2)-> e1.compareTo(e2));
return is not required when there is only one variable to be returned . Descriptive syntax for this would be
arrtosort..sort( ( e1, e2 ) -> {
int result = e1.compareTo( e2 );
return result;
} );
Example with return
Functional style can also be used with methods that have a return , example for sorting the implementation would be
return is not required when there is only one variable to be returned . Descriptive syntax for this would be
arrtosort..sort( ( e1, e2 ) -> {
int result = e1.compareTo( e2 );
return result;
} );
Example using stream
Java 8 provides a new API (called Streams) that supports many parallel operations to process data and resembles the way you might think in database query languages—you express what you want in a higher-level manner, and the implementation (here the Streams library) chooses the best low-level execution mechanism. As a result, it avoids the need for you to write code that uses synchronized, which is not only highly error prone but is also more expensive than you may realize on multicore CPUs.Here is an example to filter out only even numbers from a arraylist of integers and print them
public static void printEvenFunctional(List intArr)
{
intArr.stream().filter(e->e%2!=0).forEach(System.out::println);
}
This makes use of the Predicate interface java.util.function.Predicate .
Descriptive syntax would be
public static void printEvenFunctionalDescriptive(List intArr)
{
intArr.stream().filter(
new CheckInt()
).forEach(System.out::println); ;
}
CheckInt class would be
class CheckInt implements Predicate
{
public boolean test(Integer i)
{
return i%2==0 ;
}
}
Stream api allows code to be written that is
- Declarative— More concise and readable
- Composable— Greater flexibility
- Parallelizable— Better performance
parallelStream
above example uses sequential stream , it can be changed to parallelStream by just changingintArr.stream()
to
intArr.parallelStream()
Optional
Java8 introduces new class java.util.Optional . Its the idea inspired from Scala and Haskell and it attempts to solve the problem
public class Person{
Optional phone ;
public Optional getCellphone()
{
return phone;
}
}
ifPresent / orElse
price = phone.orElse( defaultPhone ).getPrice();
phone.ifPresent( p -> System.out.println("Phone is present for person") );
can also be applied on streams as shown below
employee.stream()
.filter(Employee::isRelocated)
.findAny()
.ifPresent( e -> System.out.println(e.getName() );
can also be applied on streams as shown below
employee.stream()
.filter(Employee::isRelocated)
.findAny()
.ifPresent( e -> System.out.println(e.getName() );
No comments:
Post a Comment