Why Java 8
python -->10 lines of code In java -->100 lines of code
1)Java 8 code is
concised code they did this by enabling functional programming
2)Most powerful concept lamda expressions to enable functional programming
3)Following is normal way of writing code
public class TestDurga {
public static int square(int n)
{
return n*n;
}
public static void main(String[] args) {
System.out.println("4 is "+square(4));
}
}
Using Java 8 we can do the following
Function<Integer,Integer> f=i->i*i;
Function<Integer,Integer> f=i->i*i;
Predicate<Integer> p=i->i%2==0;
System.out.println("4 is "+square(4));
System.out.println("5 is "+f.apply(5));
System.out.println("4 is even "+p.test(4));
System.out.println("5 is even "+p.test(5));
Main Features of Java 8
Lamda Expressions
Functional Interface
Defautl and Static Methods
Predifined Functional Interface
Producer
Consumer
Predicate
Function
Supplier
Double Colon Operator(::)
Streams
Data and Tine API
Optional Class
Nashorn Java Script Engine
Lamda Expressions
--------------------------------------------------------------
Lisp first pgming language which uses lamda expressions
Already there in many languages in ruby ,python ,java script-- It came very lately in java
Main objective of lamda expressions
----------------------------------------
1)Bring benefits of functional pgming in java
What is Lamda Expressions
-------------------------
1)Its anonymous function
*)With out return type
*)With out name
*)not having modifier
2)Very Very easy Concept
3)How to Write this lamda Expressions??
public void m1()
{
S.O.P("hello");
}
Now convert this in to lamda expressions Only usage of special symbol is required(->)
()->{S.O.P("hello");}
If body has only one line then remove curly braces
()->S.O.P("hello");
Example 2
--------------
public void m1(int a ,int b)
{
S.O.P(a+b);
}
Into Lamda expressions
(int a,int b)->s.o.p(a+b);
some times compiler can guess type automatically then no need to specify int,float ,etc
( a, b)->s.o.p(a+b);
Example 3
------------
public int squareIt(int n)
{
return n*n;
}
This in to Lamda Expressions
n -> n*n;
With out curly braces we need not specify return statement
With in curly braces if we want to return some value then we should use return statement
Example 4
----------------
public void m1(String s)
{
return s.length();
}
s->s.length();
4)How can we call this lamda expression?
------------------------------------------------------
*)FI(Functional Interface) is the special word used in this case
Annotation used here @FunctionalInterface
*)FunctionalInterface Contains the following
Runnable,Comparable,Comparator,ActionListener,Callable
All these are interfaces and contain only one method
*)Interface which contaings Single Abstract Method(SAM) are called as FI.This is required to invoke Lamda Expressions
public void m1()
{
S.O.P("hello");
}
*)Functional Interface can take any number of default and static methods but it must have only one abstract method
5)FI with respect to inheritance
If parent interface is functional interface then child interface is also FI if child does not define its own abstract method
Note :Normal Interface can contain any number of abstract methods
6)interface Intf
{
public void m1();
}
public class Test
{
p s v m()
{
Intf i = ()->s.o.p("hello");
i.m1();
}
}
To provide reference to lamda expression FI is required
Example 2:
----------------
interface Intf
{
public void add(int a ,int b);
}
public class Test
{
p s v m()
{
Intf i = ( a, b)->s.o.p("hello"+a+b);
i.add(4,4);
}
}
Comparator Example with Lamda and with out Lamda
------------------------------------------------------------------------------
Comparator has only one method
Compare(Object obj1,Object obj2);
Returns -ve if obj1<obj2
Returns +ve if obj1>obj2
Returns 0 if obj1 == obj2
OLD Implementation With Out Lamda
class MyComp implements Comparator<Integer>
{
@Override
public int compare(Integer o1, Integer o2) {
// TODO Auto-generated method stub
return (o1<02)?-1:(o1>o2)?1:0;
}
}
// OLD Implementation With Out Lamda
//Collections.sort(testList,new MyComp() );
With Lamda
Comparator< Integer> c = (o1,o2)-> (o1<02)?-1:(o1>o2)?1:0;
//With Lamda
Collections.sort(testList,c );
System.out.println("After sorting "+testList);
testList.stream().forEach(System.out::println);
o/p
prints numbers in line by line
List<Integer> finalEvenNumberList=testList.stream().filter(i->i%2==0).collect(Collectors.toList());
System.out.println(finalEvenNumberList);
o/p
prints only the even numbers
s1.compareTp(s2)--->Always applicable for alphabetical order
Refer my post Comparator example using java8 for example
Anonymous class and Lamda Expressions
--------------------------------------------------
Anonymous class are more powerful than Lamda Expression
Exmaple
---------
interface A
{
m1();
m2();
}
//Following is anonymous inner class
A a = new A()
{
public void m1()
{
}
public void m2()
{
}
};
Here in the above interface we cannot go for FI and lamda expressions since we have two abstract methods here.
Where ever Lamda expressions are there anonymous class can come
Anonymous Class can extend normal class, abstract class
Anonymous Class can implement an interface which contain any number of abstract methods
Lamda Expression can implement interface which contain single Abstract method
Default methods
--------------------------------
Untill 1.7 every method inside interface is public and abstract
From 1.8 we can take default and static methods also inside interface
From 1.9 private methods also allowed
Varialbles inside interface are always public static final
Default method also known as defender , virtual extension methods
This to avoid condition like in future if we add new method in interface then all the classes implementing interface will be effected.
Then in this scenario we declare method as default
Default method can be overrided in the implemented class.
While overriding we should use public void , we cannot use default inside the class
we cannot keep the object class metods as default methods in interface
Java does not support multiple inheritance (diamond problem , ambiguity problem)
Note:
Interface static method by default not available to implemented class.
Interface static methods should be called only by using Interface name
Main Method inside interface possible from 1.8 onwards
If all methods needs to be static then best approach is to declare all methods inside the interface and implement it in a class
Predifined Functional Interface : Predicate
---------------------------------------------------------------------------------------------------------------------
Predicate
Function
Consumer
Supplier
predicate(I)
public abstarct boolean test(T t)
interface predicate<T>
{
public boolean test(T t);
}
Function
functional
Interface Function<T,R>
{
public R apply(t t)
}
Consumer method has accept
1)Function chaining is also possible
f1.andthen(f2).apply(i); --> f1 followed by f2(f1 first and then f2 is applied)
f1.compose(f2).apply(i); --> f2 is applied first then f1 is applied
Note
Predicate reurns boolean always
Function can return any type function(T,R)
Consumeer only consumes and will not return any thing consumer<T>
For consumer also chaning is possible
Supplier
-------------------------
It never takes any input
interface supplier<R>
{
public R get();
}
Supplier for Random OTP
--------------------------
Check java class
Note
--------
predicate -->test()
Function--> apply()
Consumer --> accept()
supplier--->get()
Normal predicate takes only one argument and performs conditional check
Two input arguments then what to use because predicate Function Consumer take only one
Requirement
------------
Sum of two is even or not
then go for two argument functional interface
Bipredicate
BiFunction
-----------------------------------
Check my workspace for this example
three args----1 input 2 input third is return type
interface BiFunction<t,u,r>
{
public R apply(t,u)
}
BiConsmer
--------------------------------
Refer my workspace
Additional Functional Interface
------------------------------------------------
Predicate<Integer> p=i->i%2==0 ; this has performance issues(autoxoxing and unboxing going on)
to overcome we go for primitive version of functional interface.Since the before is applicable well for objects
IntPredicate p =i->i%2==0;
for(int x1:x )
{
if(p.test(x1))
System.out.println(x1);
}
Here in the above example no performance issues , here no autoboxing is happening
Primitive predicate types
int predicate
double predicate
long predicate
Primitive version of function types
Function<Integer,Integer> fTest=i1->i1*i1;
System.out.println(fTest.apply(8));
this has performance issues(autoxoxing and unboxing going on)
to overcome we go for primitive version of functional interface.
Primitive types of Consumer
------------------------------------
IntConsumer
DoubleConsumer
LongConsumer
Primitive Supplier
---------------------------
BooleanSupplier
getasBoolean();
IntSupplier
getasInt();
Method and Constructor reference(Alternative for Lamda expressions)
--------------------------------------------------------------------
Code reusability
:: use this operator(For method reference / constructor reference)
Can we use instance methods???
Yes we can take both instance and static methods
No worry about return type and arguments must be same
Different return types are allowed but only restriction argument types must be watched(TestDurgaMesgRef Refer this)
throw user defined exception in java
public class ExceptionTest {
public static void main(String args[]) {
int empId = 10;
try {
String userName = getUserNameById(empId);
System.out.println(userName);
} catch (UserNotFoundException ue) {
// log the exception
}
}
private static String getUserNameById(int empId) throws UserNotFoundException {
User user = userDao.getUserById(empId);
if (user == null) {
// throwing the exception here
throw new UserNotFoundException("User not present in Database");
}
return user.getName();
}
}