100% found this document useful (2 votes)
569 views85 pages

Java - 8 Features

This document discusses features introduced in Java 8, including lambda expressions, method references, default methods in interfaces, and improvements to the stream API. Key features are lambda expressions, which allow implementing functional interfaces in a more concise way, and default methods, which allow adding new methods to interfaces without breaking existing implementations. The document provides examples of using lambda expressions to iterate through collections and implement interfaces more concisely compared to previous approaches like anonymous classes.

Uploaded by

Akash Naik
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
Download as docx, pdf, or txt
100% found this document useful (2 votes)
569 views85 pages

Java - 8 Features

This document discusses features introduced in Java 8, including lambda expressions, method references, default methods in interfaces, and improvements to the stream API. Key features are lambda expressions, which allow implementing functional interfaces in a more concise way, and default methods, which allow adding new methods to interfaces without breaking existing implementations. The document provides examples of using lambda expressions to iterate through collections and implement interfaces more concisely compared to previous approaches like anonymous classes.

Uploaded by

Akash Naik
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1/ 85

Java 8

It was introduced in March 18 2014.


In this version Java add lot of features was added.
Those are:
a. Lambda Expressions.
b. Method References.
c. Functional interface.
d. Stream API.
e. Stream Filter.
f. Base64 encode and decode.
g. Default Methods interface.
h. Static methods in interface
i. forEach() method.
j. Collectors class.
k. StringJoiner class.
l. Optional Class.
m. JavaScript Nashorn.
n. Parllel array sort.
o. Parameter reflection.
p. Type annotations.

Lambda Expressions:
It is very important feature added in java 8.
Java doesn’t support functional programming up to
java 7, but from java 8 onwards java is also supports
functional interface.
It is best suitable for providing implementation for
Single abstract method interface/functional
interface/one method interface.
It will provide implementation for functional
interface in the very short format and clear manner.
It is best suitable for collection framework library.
It is the best suitable for navigating/iterating,
filtering and read or extract the data from collection
objects.
Before talk about Lambda expression first we must
and should be aware about Functional Interface.
An interface which contains exactly only one
abstract method is called Functional Interface or Single
abstract method interface or single/one method
interface.
To represents an interface as Functional Interface,
we have one annotation like @FunctionalInterface.

How to provide implementation for interface up to java


7?
1. With the support of implementation class.
Example:

interface Test{
public abstract void m1();
}
class Check implements Test{
@Override
public void m1() {
System.out.println("This is
implementation method for Test
interface.....");
}
}
public class Lambda {
public static void main(String[] s) {
Test t = new Check();
t.m1();
}
}

2. We have weapon like anonymous inner class to


provide implementation for interfaces (contains
only one method) like bellow.
Example:

interface Test{
public abstract void m1();
}

public class Lambda {


public static void main(String[] s) {
Test t = new Test() {
public void m1() {
System.out.println("This is the
implementation for Test interface...");
}
};
t.m1();
}
}
3. We have weapon like anonymous inner class to
provide implementation for interfaces (contains
more than one method) like bellow.
Example:

interface Test{
public abstract void m1();
public abstract void m2();
}

public class Lambda {


public static void main(String[] s) {
Test t = new Test() {
public void m1() {
System.out.println("This is the
implementation for Test interface...m1()");
}
public void m2() {
System.out.println("This is the
implementation for Test interface...m2()");
}
};
t.m1();
t.m2();
}
}
In the above program we are getting bellow .class files
a. Test.class
b. Lambda.class
c. Lambda$1.class
Every anonymous class is the sub or implementation
class for either class or interface.
4. From java 8 onwards we have one greater weapon
that is LAMBDA EXPRESSION.
It is suitable for Single Abstract Method Interface.

interface Test{
public abstract void m1();
}
public class Lambda {
public static void main(String[] s) {
Test t = () -> {
System.out.println("this is
implementation for Test interface"
+ " by using lamda");
};
t.m1();
}
}

In the above we are getting only two .class file like


a. Test.class
b. Lambda.class
Here no .class file like Lambda$1.class file.
That means in the above we are not writing any
class separately. This is the example highlighting
functional programming in java.
Example on anonymous inner class with zero
argument/ non-parameterized method.

interface Square{
public static final int side=50;
public abstract void area();
}
public class Lambda {
public static void main(String[] s) {
Square t = new Square() {
public void area() {
System.out.println("The area of the
square is:: "+(4*side));
}
};
t.area();
}
}

In the above program “side” not available in


anonymous inner class but it will takes from interface.
Example on Lambda Expression for Single Abstract
method interface with zero argument/non-
parameterized method.

interface Square{
public static final int side=50;
public abstract void area();
}
public class Lambda {
public static void main(String[] s) {
Square t =() -> {
System.out.println("The area of the
square is:: "+(4*side));
};
t.area();
}
}
We will get compile time error. That is can’t find
symbol variable side.
In the above side variable is not taking from the Square
interface the reason lambda is not an implementation
class of Square. It is a just function.
To overcome the above problem, take one local “side”
variable in main method like bellow.

interface Square{
public abstract void area();
}
public class Lambda {
public static void main(String[] s) {
int side=500;
Square t =() -> {
System.out.println("The area of the
square is:: "+(4*side));
};
t.area();
}
}
We can take “side” variable as static at class level like
bellow.

interface Square{
public abstract void area();
}
public class Lambda {
static int side=14;
public static void main(String[] s) {
Square t =() -> {
System.out.println("The area of the
square is:: "+(4*side));
};
t.area();
}
}
But don’t take “side” variable as non-static/instance
the reason is non-static data we can’t call directly from
static context.

interface Square{
public abstract void area();
}
public class Lambda {
int side=14;
public static void main(String[] s) {
Square t =() -> {
System.out.println("The area of the
square is:: "+(4*side));
};
t.area();
}
}
Compile Time Error: non-static variable cannot be
referenced from static context.
Program on Lambda Expression of Functional interface
which contains argument method.

interface Square{
public abstract void area(int side);
}
public class Lambda {
public static void main(String[] s) {
Square t = (side) -> {
System.out.println("The area of the square
is:: "+(4*side));
};
t.area (111);
}
}
Program on Lambda Expression of Functional interface
which contains argument method.

interface Rectangle{
public abstract void area(int length, int
breadth);
}
public class Lambda {
public static void main(String[] s) {
Rectangle t =(a,b) -> {
System.out.println("The area of the square
is:: "+(a*b));
};
t.area(10,20);
}
}

Program on Lambda Expression of functional interface


which contains non-void method.
In Java if the method is non-void method, that method
must and should be ended with return with appropriate
value.
In functional programming (Lambda Expression), no
need to write return keyword.
Example:

interface Rectangle{
public abstract int area(int length, int
breadth);
}
public class Lambda {
public static void main(String[] s) {
Rectangle t =(a,b) -> {
return a*b;
};
System.out.println(t.area(100,200));
Rectangle t1 =(a,b)->(2*(a+b));
System.out.println(t1.area(10,20));
}
}
In the last but one line don’t try to write body like
bellow.
Rectangle t1 = (a, b) ->{(2*(a+b))};
(Or)
Rectangle t1 = (a, b) ->{(2*(a+b));};

If we trying to write body we need write return keyword


after curly braces.
Rectangle t1 =(a,b)->{return 2*(a+b);};
System.out.println(t1.area(10,20));

How to trace out Collection Object elements without


Lambda Expression:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Lambda {


public static void main(String[] s) {
List<String> l = new ArrayList<String>();
l.add("nit");
l.add("kit");
l.add("nacre");
l.add("ram");
l.add("cj");
l.add("aj");
Iterator i = l.iterator();
while(i.hasNext()) {
System.out.println(i.next());
}
}
}

How to trace out Collection Object elements with


Lambda Expression:
import java.util.ArrayList;
import java.util.List;
public class Lambda {
public static void main(String[] s) {
List<String> l = new ArrayList<String>();
l.add("nit");
l.add("kit");
l.add("nacre");
l.add("ram");
l.add("cj");
l.add("aj");
l.forEach((data)-
>{System.out.println(data);});
}
}

How to trace out Collection Object elements with


Lambda Expression:
import java.util.ArrayList;
import java.util.List;

public class Lambda {


public static void main(String[] s) {
List<Integer> l = new ArrayList();
l.add(10);
l.add(20);
l.add(30);
l.add(40);
l.add(50);
l.add(60);
l.forEach((I)->{System.out.println(I);});
}
}

Program on Lambda Expression with multiple


statements in body:
interface Rectangle{
public abstract void test(int length, int
breadth);
}
public class Lambda {
public static void main(String[] args) {
Rectangle s = (length,breadth)->{
int perimeter = 2*(length+breadth);
System.out.println("perimeter:
"+perimeter);
int area = (length*breadth);
System.out.println("area: "+area);
};
s.test(100, 200);
}
}
How to create Thread by using Runnable interface:
class Test implements Runnable{
@Override
public void run() {
System.out.println("This Test class run
method");
}
}
public class Lambda {
public static void main(String[] args) {
Test t = new Test();
Thread tt = new Thread(t);
tt.start();
}
}

How to create Thread by using anonymous inner class:

public class Lambda {


public static void main(String[] args) {
Runnable r = new Runnable()
{
@Override
public void run() {
System.out.println("This is
thread: anonymous inner class");
}
};
Thread t = new Thread(r);
t.start();
}
}
How to create Thread by using Lambda Expression:
public class Lambda {
public static void main(String[] args) {
Runnable r = ()->{
System.out.println("This is thread:
Lamda Expression");
};

Thread t = new Thread(r);


t.start();
}
}

How to sort the elements on Collection Object by using


comparator without using Comparator:
import java.util.Comparator;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

import oracle.net.aso.e;
class Student{
int sid;
String sname;
Integer sage;
public Student(int sid, String sname, int sage) {
super();
this.sid = sid;
this.sname = sname;
this.sage = sage;
}
@Override
public String toString() {
return sid+"..."+sname+"..."+sage;
}
}
public class Lambda {
public static void main(String[] args) {
Student s1 = new Student(101,"ram",30);
Student s2 = new Student(102,"sam",20);
Student s3 = new Student(103,"varun",40);
Student s4 = new Student(104,"kiran",50);
Student s5 = new Student(105,"uma",10);
Set<Student> l = new TreeSet<Student>(new
MyComparator());
l.add(s1);
l.add(s2);
l.add(s3);
l.add(s4);
l.add(s5);
Iterator<Student> i = l.iterator();
while(i.hasNext()) {
System.out.println(i.next());
}
System.out.println("program finished");
}
}
class MyComparator implements Comparator{
@Override
public int compare(Object obj1, Object obj2) {
Student s1 = (Student)obj1;
Student s2 = (Student)obj2;
return -s2.sage.compareTo(s1.sage);

}
}
Lambda Expression on Collection Object sorting
elements based Student name:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
class Student{
int sid;
String sname;
int sage;
public Student(int sid, String sname, int sage) {
super();
this.sid = sid;
this.sname = sname;
this.sage = sage;
}
@Override
public String toString() {
return sid+"..."+sname+"..."+sage;
}
}
public class Lambda {
public static void main(String[] args) {
Student s1 = new Student(101,"ram",30);
Student s2 = new Student(102,"sam",20);
Student s3 = new Student(103,"varun",40);
Student s4 = new Student(104,"kiran",50);
Student s5 = new Student(105,"uma",10);
List<Student> l = new ArrayList<Student>();
l.add(s1);
l.add(s2);
l.add(s3);
l.add(s4);
l.add(s5);
Collections.sort(l, (p1 ,p2)->{
return p1.sname.compareTo(p2.sname);
});

l.forEach((data)->{
System.out.println(data);
});
}
}

Note: Don’t take variable names as private.


Lambda Expression on Collection Object for sorting the
elements based on student age:
Note: Don’t take student age in primitive data type
format. We should take wrapper class format.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
class Student{
int sid;
String sname;
Integer sage;
public Student(int sid, String sname, int sage) {
super();
this.sid = sid;
this.sname = sname;
this.sage = sage;
}
@Override
public String toString() {
return sid+"..."+sname+"..."+sage;
}
}
public class Lambda {
public static void main(String[] args) {
Student s1 = new Student(101,"ram",30);
Student s2 = new Student(102,"sam",20);
Student s3 = new Student(103,"varun",40);
Student s4 = new Student(104,"kiran",50);
Student s5 = new Student(105,"uma",10);
List<Student> l = new ArrayList<Student>();
l.add(s1);
l.add(s2);
l.add(s3);
l.add(s4);
l.add(s5);

Collections.sort(l, (p1 ,p2)->{


return p1.sage.compareTo(p2.sage);
});

l.forEach((data)->{
System.out.println(data);
});
}
}

How to use Lambda Expression on Filter Object.


import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
class Student{
int sid;
String sname;
Integer sage;
public Student(int sid, String sname, int sage) {
super();
this.sid = sid;
this.sname = sname;
this.sage = sage;
}
@Override
public String toString() {
return sid+"..."+sname+"..."+sage;
}
}
public class Lambda {
public static void main(String[] args) {
Student s1 = new Student(101,"ram",30);
Student s2 = new Student(102,"sam",20);
Student s3 = new Student(103,"varun",40);
Student s4 = new Student(104,"kiran",50);
Student s5 = new Student(105,"uma",10);
List<Student> l = new ArrayList<Student>();
l.add(s1);
l.add(s2);
l.add(s3);
l.add(s4);
l.add(s5);
Stream<Student> s= l.stream();
System.out.println(s.findFirst());
Stream<Student> ss = l.stream().filter((std)-
> std.sage>15);
ss.forEach((st)->{

System.out.println(st.sid+"..."+st.sname+"..."+st.sag
e);
});
}
}

Method References:
interface Test{
public abstract void check();
}
public class Lambda {
public static void main(String[] args) {
Test t = () -> {
System.out.println("this is test
interface check implementation");
};
t.check();
}
}

In the above program we writing one lambda expression


for providing implementation of Test interface check
method and later referencing that method.
In the above program Lambda Expression may be give a
little bit of confusion, to avoiding that confusing and
implementation separately in one method and later if
we want to pointing that method we have alternative
way that is Method References.
If we are using Method References internally that
method references will write one lambda expression.
The representation of Method References is :: (double
colon).
The above program we can rewrite as bellow by using
Method References.
interface Test{
public abstract void check();
}
public class Lambda {
public static void check() {
System.out.println("this is test interface
check implementation:Method references");
}
public static void main(String[] args) {
Test t = Lambda::check;
t.check();
}
}

We can use above method reference on top of following


programming elements.
a.Static methods.
b.Non-static/instance methods.
c.Constructors.

How to create Thread by using lambda expression to


call user define method.
public class Lambda {
public static void m1() {
System.out.println("this is thread executing
by: Lambda Expression");;
}
public static void main(String[] args) {
Runnable r = ()->m1();
Thread t = new Thread(r);
t.start();
}
}

How to create Thread by using Method Reference to


call user define method.
Note: The above program we can rewrite as bellow.
public class Lambda {
public static void m1() {
System.out.println("this is thread executing
by: Method References");;
}
public static void main(String[] args) {
Runnable r = Lambda::m1;
Thread t = new Thread(r);
t.start();
}
}

Note: This statement Runnable r = Lambda::m1;


will internally provide lambda expression like bellow
() -> m1();

How to communicating with non-static method by using


method reference:
interface Test{
public abstract void wish() ;
}
public class MethodReference {
public void wish1() {
System.out.println("this is thread
executing by: Method References");;
}
public static void main(String[] args) {
MethodReference mr = new
MethodReference();
Test t = mr::wish1;
t.wish();
}
}

Example on MethodReference and Lambda Expression to


interact with static method:
import java.util.function.BiFunction;

class Addition{
public static int addition(int a,int b) {
return a+b;
}
}
public class MethodReference {

public static void main(String[] args) {


BiFunction<Integer,Integer,Integer> bi =
(a,b)-> (a+b);
int i = bi.apply(10, 20);
System.out.println("i: "+i);

BiFunction<Integer,Integer,Integer> bi1 =
(a,b)->{
return (a+b);

};
int j = bi.apply(10, 20);
System.out.println("j: "+j);

BiFunction<Integer, Integer, Integer> mr =


Addition::addition;
int k = mr.apply(500, 300);
System.out.println("k: "+k);
}
}

Example on MethodReference for overloading static


methods:
import java.util.function.BiFunction;

class Addition{
public static int addition(int a,int b) {
return a+b;
}
public static float addition(int a,float b) {
return a+b;
}

public static String addition(String a,String b)


{
return a+b;
}

}
public class MethodReference {

public static void main(String[] args) {

BiFunction<Integer, Integer, Integer> mr =


Addition::addition;
int i = mr.apply(500, 300);
System.out.println("i: "+i);

BiFunction<Integer, Float, Float> mr1 =


Addition::addition;
float j = mr1.apply(50, 300.00f);
System.out.println("j: "+j);

BiFunction<String, String, String> mr2 =


Addition::addition;
String k = mr2.apply("ram", "chandra");
System.out.println("k: "+k);
}
}

Example on MethodReference to communicating with non-


static methods:
import java.util.function.BiFunction;

class Addition{
public int addition(int a,int b) {
return a+b;
}
public float addition(int a,float b) {
return a+b;
}

public String addition(String a,String b) {


return a+b;
}

}
public class MethodReference {

public static void main(String[] args) {


BiFunction<Integer, Integer, Integer> mr =
new Addition()::addition;
int i = mr.apply(500, 300);
System.out.println("i: "+i);

BiFunction<Integer, Float, Float> mr1 = new


Addition()::addition;
float j = mr1.apply(50, 300.00f);
System.out.println("j: "+j);

BiFunction<String, String, String> mr2 = new


Addition()::addition;
String k = mr2.apply("ram", "chandra");
System.out.println("k: "+k);
}
}

Example on MethodReference to communicating with


constructor:
interface Test{
Addition add(int a, int b);
}
class Addition{
Addition(int a, int b){
System.out.println("this is addition class:
"+(a+b));
}
}
public class MethodReference {
public static void main(String[] args) {
Test t = Addition::new;
t.add(10,20);
}
}

Examples on java.util.function.Predicate:
Example1:
import java.util.function.Predicate;

public class Test1 {


public static void main(String[] args) {
Predicate<Integer> p = (x)-> x>5;
boolean b = p.test(10);
System.out.println("b: "+b);

Predicate<Boolean> p1 = (y)-> y==true ;


boolean b1 = p1.test(true);
System.out.println("b1: "+b1);
}
}

Example2:
import java.util.ArrayList;
import java.util.function.Predicate;

class Student{
int sid;
String sname;
Student(int sid,String sname){
this.sid = sid;
this.sname = sname;
}
public String getSname() {
return sname;
}
}
public class Test1 {
public static void main(String[] args) {
ArrayList<Student> al = new
ArrayList<Student>();
Student s1 = new Student(101,"ram");
Student s2 = new Student(102,"sam");
Student s3 = new Student(103,"kiran");

al.add(s1);
al.add(s2);
al.add(s3);

Predicate<Student> p = (obj) ->


obj.getSname().startsWith("s");
/*boolean b = p.test(s2);
System.out.println(b);*/
al.forEach(x ->{
System.out.println("--------");
if(p.test(x)) {
System.out.println(x.getSname());
};
});
}
}

Program on java.util.function.BiPredicate
import java.util.function.BiPredicate;
public class Test{
public static void main(String[] args) {
BiPredicate<Integer,Integer> bi1 = (x,y)-> x>y ;
boolean b2 = bi1.test(20, 10);
System.out.println("b2: "+b2);
BiPredicate<Integer,Integer> bi2 = (x,y)-> x>y ;
boolean b3 = bi2.test(10, 20);
System.out.println("b3: "+b3);
}
}

Example on java.util.function.Function:
Example1:
import java.util.function.Function;

public class Test1 {


public static void main(String[] args) {
Function<Integer,String> fun = (f) -> "The
result is: "+f;
String f1 = fun.apply(10);
System.out.println("f1: "+f1);

Function<Integer,String> fun1 = (f) -> {


if(f >10 ) {
return "Given Number Is:
"+f+" greater than 10";
}
else return "Given Number Is:
"+f+" lessthan 10";
};
}
}

import java.util.function.Function;

public class Test1 {


public static void main(String[] args) {
Function<Integer,Double> fun = (f) ->
(double)f;
double d=fun.apply(10);
System.out.println("d: "+d);

Function<Integer,Double> fun1 = (f) -> {


if(f>10) {
return (double)f;
}
else {
double x = (double)f;
return -x;
}
};
double d1=fun1.apply(10);
System.out.println("d1: "+d1);

}
}

Example on java.util.function.BiFunction:
Example1:
import java.util.function.BiFunction;
public class Test1 {
public static void main(String[] args) {
BiFunction<Integer,Integer,String> b = (n1,n2)->
"the addition is: "+
(n1+n2);
String s = b.apply(100, 200);
System.out.println("s: "+s);
BiFunction<Integer,Integer,Integer> b1 =
(n1,n2) -> (n1+n2);
int i = b1.apply(11,22);
System.out.println("i: "+i);
}
}

import java.util.function.BiFunction;
public class Test1 {
public static void main(String[] args) {
BiFunction<Integer,Integer,Double> b1 = (n1,n2) ->
{ if(n1>10 && n2>10) {
return (double)(n1+n2);
}
return (double)(n1-n2);
};
double d = b1.apply(50, 60);
System.out.println("d: "+d);
double d1 = b1.apply(10, 5);
System.out.println("d1: "+d1);

}
}

import java.util.function.BiFunction;
public class Test1 {
public static void main(String[] args) {
BiFunction<Integer,Integer,Double> b1 =
(n1,n2) -> (double)(n1+n2);
double d = b1.apply(50, 60);
System.out.println("d: "+d);
double d1 = b1.apply(10, 5);
System.out.println("d1: "+d1);
}
}

Program on java.util.function.Consumer:
import java.util.function.Consumer;
public class Test1 {
public static void main(String[] args)
{ Consumer<Integer> c = (value)->
System.out.println(value);
c.accept(10);
Consumer<String> c1 = (value) ->{
System.out.println(value);
};
c1.accept("ram");

Consumer<Integer> c2 = (value) ->{


if(value >10) {
System.out.println("Given value "+value+" is
greaterthan 10 ");
}
else if(value < 10) {
System.out.println("Given value "+value+" is lessthan
10 ");
}
else
System.out.println("Given value "+value+" is equal to
10 ");
};
c2.accept(20);
c2.accept(9);
c2.accept(10);
}
}

Example on java.util.function.BiConsumer:

import java.util.function.BiConsumer;
public class Test{
public static void main(String[] args) {
BiConsumer<Integer,Integer> bic = (a,b) ->
System.out.println(a+b);
bic.accept(100, 200);
BiConsumer<Integer,String> bic1 = (a,b) ->
System.out.println(a+b);
bic1.accept(100, "good");
BiConsumer<String,String> bic2 = (a,b) ->
System.out.println(a+b);
bic2.accept("ram", "chandra");
}
}

Example on java.util.function.Supplier:
import java.util.Random;
import java.util.function.Supplier;

public class Test1 {


public static void main(String[] args) {
Supplier<String> sup = ()-> {
return "ram";
};
String s1 = sup.get();
System.out.println("s1: "+s1);

Supplier<Integer> sup1 = ()->{


int[] a =
{10,20,30,40,50};
Random r =
new Random();
int b =
r.nextInt(5);

System.out.println("b: "+b);
return a[b];
};
int i1 = sup1.get();
System.out.println("i1: "+i1);
int i2 = sup1.get();
System.out.println("i2: "+i2);
int i3 = sup1.get();
System.out.println("i3: "+i3);
int i4 = sup1.get();
System.out.println("i4: "+i4);
int i5 = sup1.get();
System.out.println("i5: "+i5);
}
}

Program on BinaryOperator and UnaryOperator:


import java.util.function.BinaryOperator;
import java.util.function.UnaryOperator;

public class Test{


public static void main(String[] args) {
UnaryOperator<Integer> uo = (x) -> x*10;
int i = uo.apply(10);
System.out.println(i);

BinaryOperator<String> bo = (x,y) -> x+y;


String s = bo.apply("ram", "chandra");
System.out.println("s: "+s);
}
}

Functional Interface:
An interface which contains only one abstract method
is called Functional interface.
Interface I{
Public abstract void m1();
}
It may contain more than one default methods.
Interface J{
Public abstract void m1();
Default void m2(){
}
Default void m3(){
}
}
It may contain more than one static method also.
Interface J{
Public abstract void m1();
static void m2(){
}
static void m3(){
}
}
We can declare more than one of java.lang.Object class
methods.
@FunctionalInterface
interface J{
public abstract void m1();
static void m2(){
}
static void m3(){
}
default void m4() {

}
default void m5() {

}
@Override
public String toString();
@Override
public int hashCode();
}

It is suitable for developing Functional Programming in


java.
Example on above all instructions of Function
Interface.
@FunctionalInterface
interface J{
public abstract void m1();
static void m2(){
System.out.println("static m2 method");
}
static void m3(){
System.out.println("static m3 method");
}
default void m4() {
System.out.println("default m4 method");
}
default void m5() {
System.out.println("default m5 method");
}
@Override
public String toString();
@Override
public int hashCode();
}

public class Test implements J {


public void m1() {
System.out.println("this implementation of
abstract method in J");
}
public static void main(String[] args) {
J obj = new Test();
obj.m1();
J.m2();
J.m3();
//J.m4();//invalid
//J.m5();//invalid
obj.m4();
obj.m5();
}
}

In the above program in interface ‘J’ there three


abstract methods like m1(), toString(), hashCode().
In our Test class we are giving only implementation
for m1(), but not for toString(), hashCode(). In this
process we are not getting any error, the reason is
by default Test class is the subclass of java.lang.
Object. So implementatios for toString() and
hashCode() by default coming to Test class from
java.lang.Object class.

Example on Functional Interface:


@FunctionalInterface
interface J{
public abstract void m1();
}
@FunctionalInterface
interface K{
public abstract void m2();
}

public class Test implements K {


public void m1() {
System.out.println("m1 method");
}
public void m2() {
System.out.println("m2 method");
}
public static void main(String[] args) {
K obj = new Test();
obj.m2();
}
}

Note 1: In the above program if our interface K


implements J then our J is not a functional interface
the reason K having two abstract methods one is m1()
and second one m2() due to inheritance. It is
violating the rules of functional interface.

@FunctionalInterface
interface J{
public abstract void m1();
}
@FunctionalInterface
interface K implements J{
public abstract void m2();
}

Note 2: If we avoid writing @FunctionalInterface


annotation on ‘K’ then ‘K’ is becomes a normal
interface.
@FunctionalInterface
interface J{
public abstract void m1();
}

interface K extends J{
public abstract void m2();
}
public class Test implements K {
public void m1() {
System.out.println("m1 method");
}
public void m2() {
System.out.println("m2 method");
}
public static void main(String[] args) {
K obj = new Test();
obj.m2();
obj.m1();
}
}

Is functional interface extends the other normal


interface?
A: Yes.

interface J{
public default void m1() {
System.out.println("defalut method m1() from
J interface");
}
}
@FunctionalInterface
interface K extends J{
public abstract void m2();
}

public class Test implements K {


public void m2() {
System.out.println("m2 method");
}
public static void main(String[] args) {
K obj = new Test();
obj.m2();
obj.m1();
}
}

Note: Normal interface or non-functional interface (J)


should have only default and static methods, if ‘J’ have
any abstract method then ‘K’ is not become a
functional interface, the reason is due inheritance
concept Function interface like ‘K’ will get two
methods like m3() and m2(), this is violating the rules
of functional interface. Bellow code is invalid.

interface J{
public default void m1() {
System.out.println("defalut method m1() from
J interface");
}
public abstract void m3();
}
@FunctionalInterface
interface K extends J{
public abstract void m2();
}

public class Test implements K {


public void m2() {
System.out.println("m2 method");
}
public static void main(String[] args) {
K obj = new Test();
obj.m2();
obj.m1();
}
}

Default Methods in Interface:

In java 8 we can able to write default methods in


interface.
These are contains body.
The main advantage of default method is without
changing the code in implementation classes we can
provide extra functionalities.

interface I{
public abstract void m1();
}
class A implements I{
public void m1() {
System.out.println("m1-A");
}
}
class B implements I{
public void m1() {
System.out.println("m1-B");
}
}
public class Test{
public static void main(String[] args) {
I obj = new A();
obj.m1();
obj = new B();
obj.m1();
}
}

In the above example if we want to add new feature to


interface ‘I’, definitely we need to change the code in
class ‘A’ and ‘B’. Like bellow
interface I{
public abstract void m1();
public abstract void m2();
}
class A implements I{
public void m1() {
System.out.println("m1-A");
}
public void m2() {
System.out.println("m2-A");
}
}
class B implements I{
public void m1() {
System.out.println("m1-B");
}
public void m2() {
System.out.println("m2-B");
}
}
public class Test{
public static void main(String[] args) {
I obj = new A();
obj.m1();
obj = new B();
obj.m1();
}
}

In the above program we did add m2() method in


interface ‘I’, so we did add extra methods in class ‘A’
and ‘B’ also.
To avoiding this problem we can do the following
things.
By using Adapter classes we can solve the above
problem like no need change the class like ‘A’ and ‘B’
like bellow:
interface I{
public abstract void m1();
public abstract void m2();
}
abstract class AC implements I{
public void m2() {}
}
class A extends AC{
public void m1() {
System.out.println("m1-A");
}
}
class B extends AC{
public void m1() {
System.out.println("m1-B");
}
}
public class Test{
public static void main(String[] args) {
I obj = new A();
obj.m1();
obj = new B();
obj.m1();
}
}

In above program we taking one adapter class like ‘AC’


and providing empty implementation to m2() and
instead of implements ‘I’ by A and B classes we should
extends the adapter class like ‘AB’
In the above approach also we did some modification
on class ‘A’ and ‘B’.
Without touching ‘A’ and ‘B’ classes if we want add new
feature to interfaces we should use ‘DEFAULT
METHOD’ in interface.
If we declare any concrete method as default method
we should mention ‘default’ keyword in its prototype
nothing but method body.

Example on default method in interface:


interface I{
public abstract void m1();
default public void m2() {
System.out.println("this is default method in
interface");
}
}
class A implements I{
public void m1() {
System.out.println("m1-A");
}
}
class B implements I{
public void m1() {
System.out.println("m1-B");
}
}
public class Test{
public static void main(String[] args) {
I obj = new A();
obj.m1();
obj.m2();
obj = new B();
obj.m1();
obj.m2();
}
}

Default method can participated in overriding also.


Like bellow.
interface I{
public abstract void m1();
default public void m2() {
System.out.println("this is default method in
interface");
}
}
class A implements I{
public void m1() {
System.out.println("m1-A");
}
@Override
public void m2() {
System.out.println("this is override method
of interface-A");
}

}
class B implements I{
public void m1() {
System.out.println("m1-B");
}
@Override
public void m2() {
System.out.println("this is override method
of interface-B");
}

}
public class Test{
public static void main(String[] args) {
I obj = new A();
obj.m1();
obj.m2();
obj = new B();
obj.m1();
obj.m2();
}
}

Note: Default methods are allowed only in interface but


in class and abstract classes.
Difference between abstract class and interfaces:

Rules of default methods:


It participated in method overloading:
interface I{
public abstract void m1();
default public void m2() {
System.out.println("this is default method in
interface");
}
default public void m2(int x) {
System.out.println("this is default method in
interface");
}
}
It can be participated in method overriding.
We can’t override default method as static method.
interface I{
public abstract void m1();
default public void m2() {
System.out.println("this is default method in
interface");
}

class A implements I{
public void m1() {
System.out.println("m1-A");
}
//bellow code is invalid.
@Override
static public void m2() {
System.out.println("this is override method
of interface-A");
}

}
In the above program we will get error.

Default method should be different from


java.lang.Object class methods:
interface I{
public abstract void m1();
default String toString() {
return "ram";
}
}

Below code will give compile time error.


interface I{
default void m1() {
System.out.println("defalut method of
interface-I");
}
}
interface J{
default void m1() {
System.out.println("defalut method of
interface-J");
}
}
class A implements I,J{
public static void main(String[] args) {
A obj = new A();
}
}

To overcome the above problem we should override


default method in our class ‘A’ like bellow.
interface I{
default void m1() {
System.out.println("defalut method of
interface-I");
}
}
interface J{
default void m1() {
System.out.println("defalut method of
interface-J");
}
}
class A implements I,J{
public void m1() {
System.out.println("defalut method of
interface-A");
}
public static void main(String[] args) {
A obj = new A();
obj.m1();
}
}

We can convert default method as abstract method in


abstract class, but concrete method we can’t convert
into abstract methods in abstract class. Like bellow.
interface I{
default void m1() {
System.out.println("defalut method of
interface-I");
}
}
abstract class AC implements I{
/*@Override
public void m1() {

}*/
public abstract void m1();
public void m2() {}
}
abstract class AC1 extends AC{
public void m2();//invalid
}
In the above program AC1 related method will give
compile time error.

STATIC METHOD IN INTERFACE:


If we want to write body method in interface we have
concept like default method. To execute interface
default method, we should required implementation
class of that interface.
interface I{
default void m1() {
System.out.println("default method in
interface-I");
}
}
class A implements I{
}
public class Test{
public static void main(String[] args) {
I obj = new A();
obj.m1();
}
}

With the support of anonymous inner class we can


override default method and we can able to call
anonymous inner class override method but not
interface default method.
interface I{
default void m1() {
System.out.println("default method in
interface-I");
}
}
public class Test{
public static void main(String[] args) {
I obj1 = new I(){
public void m1() {
System.out.println("this is
annonymous m1()");
}
};
obj1.m1();
}
}

Without any implementation class support, if we want


execute the body methods of interface, we should go
for static methods.
interface I{
static void m1() {
System.out.println("default method in
interface-I");
}
}
public class Test{
public static void main(String[] args) {
I.m1();

}
}

Static methods of interface never override.


interface I{
static void m1() {
System.out.println("default method in
interface-I");
}
}
class A implements I{
@Override void m1() {//invalid

}
}
public class Test{
public static void main(String[] args) {

I obj1 = new I(){


@Override
public void m1() {//invalid
System.out.println("this is
annonymous m1()");
}
};
}
}

Streams:
A new package like java.util.Stream introduced in java
8.
It is the collection of classes, interfaces and enum for
doing functional programming.

Programming on Collection object copy the data from


one ArrayList object to another ArrayList based on
some condition.
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

public class StreamDemo {


public static void main(String[] args) {
ArrayList<Integer> al1 = new
ArrayList<Integer>();
al1.add(10);
al1.add(20);
al1.add(30);
al1.add(40);
al1.add(50);
al1.add(60);
al1.add(70);
al1.add(80);
ArrayList<Integer> al2 = new
ArrayList<Integer>();
//without stream api
Iterator<Integer> i = al1.iterator();
while(i.hasNext()) {
Integer j = i.next();
if(j>=39) {
al2.add(j);
}
}
System.out.println(al2);
}
}

Programming on Collection object copy the data from


one ArrayList object to another ArrayList based on
some condition.
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

public class StreamDemo {


public static void main(String[] args) {
ArrayList<Integer> al1 = new
ArrayList<Integer>();
al1.add(10);
al1.add(20);
al1.add(30);
al1.add(40);
al1.add(50);
al1.add(60);
al1.add(70);
al1.add(80);
ArrayList<Integer> al2 = new
ArrayList<Integer>();
//without stream api
Iterator<Integer> i = al1.iterator();
while(i.hasNext()) {
Integer j = i.next();
if(j>=39) {
al2.add(j);
}
}
System.out.println(al2);
//with stream api
List<Integer> al3 = al1.stream().filter(v->
v>30).
map(v-
>v).collect(Collectors.toList());
System.out.println(al3);
List<Integer> al4 = al1.stream().filter(n-
>n>50).collect(Collectors.toList());
System.out.println(al4);
}
}

Programming on Collection object with user define


objects and copy the data from one ArrayList object to
another ArrayList based on some condition(age>19).

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
class Students{
public int sid;
public String sname;
public int sage;
Students(int sid,String sname,int sage){
this.sid = sid;
this.sname = sname;
this.sage = sage;
}
}
public class StreamDemo {
public static void main(String[] args) {
ArrayList<Students> al1 = new
ArrayList<Students>();
Students s1 = new Students(101,"ram1",25);
Students s2 = new Students(102,"ram2",15);
Students s3 = new Students(103,"ram3",35);
Students s4 = new Students(104,"ram4",5);
Students s5 = new Students(105,"ram5",23);
Students s6 = new Students(106,"ram6",39);
Students s7 = new Students(107,"ram7",18);
Students s8 = new Students(108,"ram8",17);
al1.add(s1);
al1.add(s2);
al1.add(s3);
al1.add(s4);
al1.add(s5);
al1.add(s6);
al1.add(s7);
al1.add(s8);
//with stream api
List<Integer> al3 = al1.stream().filter(p ->
p.sage > 19)
.map(p ->
p.sage).collect(Collectors.toList());
System.out.println(al3);

List<String> li = al1.stream().filter(p-
>p.sage>25).map(p->p.sname).
collect(Collectors.toList());
System.out.println(li);
}
}

ArrayList with Predefine Integer Objects– removeIf();


import java.util.ArrayList;
import java.util.function.Predicate;

public class StreamDemo {


public static void main(String[] args) {
ArrayList<Integer> al = new
ArrayList<Integer>();
al.add(10);
al.add(20);
al.add(30);
al.add(40);
al.add(50);
al.add(60);
al.add(70);
al.add(80);
System.out.println("al: "+al);
Predicate<Integer> p = (p1 ->p1>40);
al.removeIf(p);
System.out.println("al: "+al);
}
}
ArrayList with Predefine String Objects– removeIf();
import java.util.ArrayList;
import java.util.function.Predicate;

public class StreamDemo {


public static void main(String[] args) {
ArrayList<String> al1 = new
ArrayList<String>();
al1.add("ram");
al1.add("sam");
al1.add("varun");
al1.add("Kiran");
al1.add("baby");
System.out.println("al1: "+al1);
Predicate<String> p = (p1-
>p1.charAt(0)=='r');
al1.removeIf(p);
System.out.println("al1: "+al1);
}
}

ArrayList with user define object(Student):


removeIf():
import java.util.ArrayList;
import java.util.Iterator;
import java.util.function.Predicate;
class Students{
public int sid;
public String sname;
public int sage;
Students(int sid,String sname,int sage){
this.sid = sid;
this.sname = sname;
this.sage = sage;
}
@Override
public String toString() {
return sid+"..."+sname+"..."+sage;
}
}
public class StreamDemo {
public static void main(String[] args) {
ArrayList<Students> al1 = new
ArrayList<Students>();
Students s1 = new Students(101,"ram1",25);
Students s2 = new Students(102,"ram2",15);
Students s3 = new Students(103,"ram3",35);
Students s4 = new Students(104,"ram4",5);
Students s5 = new Students(105,"ram5",23);
Students s6 = new Students(106,"ram6",39);
Students s7 = new Students(107,"ram7",18);
Students s8 = new Students(108,"ram8",17);
al1.add(s1);
al1.add(s2);
al1.add(s3);
al1.add(s4);
al1.add(s5);
al1.add(s6);
al1.add(s7);
al1.add(s8);
System.out.println("al1: "+al1);
Predicate<Students> p = (p1->p1.sage>20);
al1.removeIf(p);
Iterator<Students> i = al1.iterator();
while(i.hasNext()) {
System.out.println(i.next());
}
}
}

Methods of Predicate:
import java.util.ArrayList;
import java.util.function.Predicate;

public class StreamDemo {


public static void main(String[] args) {
ArrayList<Integer> al1 = new
ArrayList<Integer>();
al1.add(6);
al1.add(18);
al1.add(12);
al1.add(15);
al1.add(4);
al1.add(8);
al1.add(24);
al1.add(10);
System.out.println("al1: "+al1);
//Predicate<Integer> p = (p1->p1%2==0);
Predicate<Integer> p = (p1->p1%3==0);
al1.removeIf(p);
System.out.println("al1: "+al1);

}
}
Example on and() and or() method of predicate:

import java.util.ArrayList;
import java.util.function.Predicate;
public class StreamDemo {
public static void main(String[] args) {
ArrayList<Integer> al1 = new
ArrayList<Integer>();
al1.add(6);
al1.add(18);
al1.add(12);
al1.add(15);
al1.add(4);
al1.add(8);
al1.add(24);
al1.add(10);
System.out.println("al1: "+al1);
Predicate<Integer> p1 = (p3->p3%2==0);
Predicate<Integer> p2 = (p3->p3%3==0);
System.out.print(" : ");
for(Integer i : al1) {
/*if(p1.and(p2).test(i)) {
System.out.print(i+", ");
}*/
if(p1.or(p2).test(i))
System.out.print(i+", ");
}
System.out.println();
System.out.println("al1: "+al1);

}
}

Program on predicate to select negative numbers:


import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

public class StreamDemo {


public static void main(String[] args) {
Predicate<Integer> negative = n -> (n < 0) ;
List<Integer> numbers =
Arrays.asList(10,20,30,-10,-20,-30);
long negativeCount=
numbers.stream().filter(negative).count();
System.out.println("Count of negative numbers in
list numbers = "
+ negativeCount);
}
}

Program on negative() of predicate:

import java.util.function.Predicate;

public class StreamDemo {


public static void main(String[] args) {
Predicate<Integer> greaterThanTen = (i) -> i > 10;

// Creating predicate
Predicate<Integer> lowerThanTwenty = (i) -> i <
20;
boolean result =
greaterThanTen.and(lowerThanTwenty).test(25);
System.out.println(result);

// Calling Predicate method


boolean result2 =
greaterThanTen.and(lowerThanTwenty).negate().test(25)
;
System.out.println(result2);
}
}

Program on isEquals() and test() of predicate:


import java.util.Objects;
import java.util.function.Predicate;
public class StreamDemo {
public static void main(String[] args) {
boolean p = Objects.equals("ram", "ram");
System.out.println(p);
boolean p1 = Objects.equals("ram", "ram1");
System.out.println(p1);
System.out.println("===================");
Predicate<Integer> p2 =
Predicate.isEqual(10);
boolean b = p2.test(10);
System.out.println("b: "+b);
}
}

Program on forEach() of ArrayList to read the data


from Collection object.

import java.util.ArrayList;
import java.util.function.Consumer;
public class StreamDemo {
public static void main(String[] args) {
ArrayList<Integer> al = new
ArrayList<Integer>();
al.add(10);
al.add(20);
al.add(30);
al.add(40);
al.add(50);
al.add(60);
al.add(70);
System.out.println("al: "+al);
System.out.println("===================");
al.forEach(System.out::println);
System.out.println("===================");
Consumer<Integer> c = (p) ->{System.out.println(p);};
al.forEach(c);
}
}

Program on forEach() of ArrayList by using String


objects:

import java.util.ArrayList;
import java.util.function.Consumer;
public class StreamDemo {
public static void main(String[] args) {
ArrayList<String> al = new
ArrayList<String>();
al.add("ram");
al.add("sam");
al.add("kiran");
al.add("varun");
al.add("mahi");
al.add("vani");
System.out.println("al: "+al);
System.out.println("===================");
al.forEach(System.out::println);
System.out.println("===================");
Consumer<String> c=(p)-
>{System.out.println(p.toUpperCase());};
al.forEach(c);
}
}

How to create Stream object:


import java.util.ArrayList;
import java.util.stream.Stream;
public class StreamDemo {
public static void main(String[] args) {
ArrayList<Integer> al = new
ArrayList<Integer>();
al.add(10);
al.add(20);
al.add(30);
al.add(40);
al.add(50);
al.add(60);
al.add(70);
System.out.println("al: "+al);
System.out.println("===================");
Stream<Integer> s = al.stream();
Stream<Integer> s1 = al.stream();
System.out.println(s.count());
System.out.println(s1.findFirst());
System.out.println(s.toString());
}
}
Program on forEachOrder() of Stream object:
import java.util.ArrayList;
import java.util.stream.Stream;
public class StreamDemo {
public static void main(String[] args) {
ArrayList<Integer> al = new
ArrayList<Integer>();
al.add(10);
al.add(20);
al.add(40);
al.add(30);
al.add(70);
al.add(60);
al.add(70);
System.out.println("al: "+al);
System.out.println("===================");
Stream<Integer> s = al.stream();
s.forEachOrdered(System.out::println);

}
}

Program on filter() of Stream object:


import java.util.ArrayList;
import java.util.stream.Stream;
public class StreamDemo {
public static void main(String[] args) {
ArrayList<String> al = new
ArrayList<String>();
al.add("ram");
al.add("sam");
al.add("kiran");
al.add("ramya");
al.add("ravi");
al.add("mahesh");
al.add("vani");
System.out.println("al: "+al);
System.out.println("===================");
Stream<String> s = al.stream();
s.forEachOrdered(System.out::println);
System.out.println("===================");
Stream<String> s1 = al.stream();
Stream<String> s2 = s1.filter((p)->{return
p.startsWith("r");});
//s2.forEach(System.out::println);
s2.forEachOrdered(System.out::println);
}
}

import java.util.ArrayList;
import java.util.stream.Stream;

public class StreamDemo {


public static void main(String[] args) {
ArrayList<Integer> al = new
ArrayList<Integer>();
al.add(10);
al.add(5);
al.add(15);
al.add(30);
al.add(20);
al.add(40);
al.add(35);
Stream<Integer> s = al.parallelStream();
Stream<Integer> s1 = s.filter((p)->p>20);
s1.forEach(System.out::println);
}
}

Program on map() of stream object


import java.util.ArrayList;
import java.util.stream.Stream;
public class StreamDemo {
public static void main(String[] args) {
ArrayList<String> al = new
ArrayList<String>();
al.add("ram");
al.add("sam");
al.add("kiran");
al.add("ramya");
al.add("ravi");
al.add("mahesh");
al.add("vani");
System.out.println("al: "+al);
System.out.println("===================");
Stream<String> s = al.stream();
Stream<Integer> s1 = s.map((v)->{return
v.length();});
//s1.forEach(System.out::println);
int result = s1.mapToInt(Integer::new).sum();
System.out.println(result);
}
}

Program on IntStream and DoubleStream:


import java.util.ArrayList;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class StreamDemo {
public static void main(String[] args) {
ArrayList<String> al = new
ArrayList<String>();
al.add("ram");
al.add("sam");
al.add("kiran");
al.add("ramya");
al.add("ravi");
al.add("mahesh");
al.add("vani");
System.out.println("al: "+al);
System.out.println("===================");
Stream<String> s = al.stream();
Stream<Integer> s1= s.map((v)->{return v.length();});
//s1.forEach(System.out::println);
/*IntStream s2 = s1.mapToInt(Integer::new);
System.out.println(s2.sum());*/
DoubleStream s3 =
s1.mapToDouble(Double::new);
System.out.println(s3.sum());
}
}
Program on reduce method of Stream object:
import java.util.Arrays;
import java.util.stream.IntStream;

public class StreamDemo {


public static void main(String[] args) {
int a[] = {10,20,30,40,50};
IntStream s = Arrays.stream(a);
int sum = s.reduce(0,(x,y)->{
return (x+y);
}
);
System.out.println("sum: "+sum);
}
}

Program max() and min() of Stream objects:


import java.util.ArrayList;
import java.util.stream.Stream;

public class StreamDemo {


public static void main(String[] args) {
ArrayList<Integer> al = new
ArrayList<Integer>();
al.add(10);
al.add(5);
al.add(15);
al.add(30);
al.add(20);
al.add(40);
al.add(35);
Stream<Integer> s = al.stream();
System.out.println(s.max((a,b)->{
return a.compareTo(b);
}
));
Stream<Integer> s1 = al.stream();
System.out.println(s1.min((a,b)->{
return a.compareTo(b);
}
));
}
}

Java.util.StringJoiner:

public class StreamDemo {


public static void main(String[] args) {
String[] s = {"ram","sam","varun"};
String s1 = String.join("--", s);
System.out.println(s1);

}
}

import java.util.StringJoiner;

public class StreamDemo {


public static void main(String[] args) {
StringBuilder s1 = new StringBuilder();
s1.append("ram");
s1.append("kiran");
s1.append("varun");
System.out.println(s1);

StringJoiner sj = new StringJoiner("__");


sj.add("ram");
sj.add("kiran");
sj.add("varun");
System.out.println(sj);
}
}

import java.util.StringJoiner;

public class StreamDemo {


public static void main(String[] args) {
StringJoiner sj1 = new StringJoiner("--",
"[", "]");
sj1.add("ram");
sj1.add("kiran");
sj1.add("varun");
System.out.println(sj1);
StringJoiner sj2 = new StringJoiner(",");
sj2.add("friends");
sj2.add("relatives");
System.out.println(sj2);
sj1.merge(sj2);
System.out.println(sj1);
}
}

import java.util.ArrayList;
import java.util.StringJoiner;

public class StreamDemo {


public static void main(String[] args) {
ArrayList<String> al = new
ArrayList<String>();
al.add("ram");
al.add("kiran");
al.add("varun");
System.out.println("al: "+al);
StringJoiner sj = new StringJoiner("-");
for(String s1 : al) {
sj.add(s1);
}
System.out.println("sj: "+sj);

String s2 = sj.toString();
System.out.println("s2: "+s2);
}
}

Optional Class in java:


public class StreamDemo {
public static void main(String[] args) {
String[] s =
{"ram","kiran","varun","mahi","hi"};
System.out.println(s[4].toUpperCase());
System.out.println(s[5].toUpperCase());
}
}

In the above scenario we will get one output is HI


and later we will get ArrayIndexOutOfBoundsException.

To overcome this problem we have alternative like


Optional class.

import java.util.Optional;

public class StreamDemo {


public static void main(String[] args) {
String[] s =
{"ram","kiran","varun","mahi","hi"};
System.out.println(s[4].toUpperCase());

Optional<String> o =
Optional.ofNullable(s[3]);
if(o.isPresent()) {
System.out.println(s[3].toUpperCase());
}
else {
System.out.println("there is no value in
that index");
}
}
}
In the above program we have s[3] value like mahi it
will converting into MAHI.
import java.util.Optional;
public class StreamDemo {
public static void main(String[] args) {
String[] s = new String[15];

Optional<String> o =
Optional.ofNullable(s[3]);
if(o.isPresent()) {
System.out.println(s[3].toUpperCase());
}
else {
System.out.println("there is no value in
that index");
}
}
}
In the above scenario there is no value in that index
position but still we are not getting exception
simply it will showing like following message on
console.
There is no value in that index.

import java.util.Optional;

public class StreamDemo {


public static void main(String[] args) {
String[] s = new String[15];
Optional<String> o =
Optional.ofNullable(s[3]);
o.ifPresent(System.out::println);
s[3]="ram chandra rao";
Optional<String> o1 =
Optional.ofNullable(s[3]);
o1.ifPresent(System.out::println);
System.out.println(o1.get());
System.out.println("---------------");
}
}

import java.util.Optional;

public class StreamDemo {


public static void main(String[] args) {
String[] str = new String[10];
str[5] = "ram";
Optional<String> empty =
Optional.empty();
System.out.println(empty);
Optional<String> value =
Optional.of(str[5]);
System.out.println(value.get());
System.out.println(value.hashCode());
System.out.println(value.isPresent());
value.ifPresent(System.out::println);

System.out.println(value.ofNullable(str[5]));
System.out.println(empty.orElse("value is
not present"));
System.out.println(value.orElse("value is
not present"));
}
}
import java.util.Optional;
import java.util.stream.Stream;

public class StreamDemo {


public static void main(String[] args) {
Stream <Integer> s =
Stream.of(10,20,30,40,50);
// s.forEach(System.out::println);
Optional<Integer> s1 = s.findFirst();
if(s1.isPresent()) {
System.out.println(s1);
}
}
}

Java Nashorn
It is java script engine. We can call and execute the
java script code directly from our command prompt by
using following command like “jjs”.

Following steps are useful to work with java nashorn.


1.Take one notepad.
2.Type following code in that notepad.
var message = function(){
print("this is new feature.....");
};
message();
3. Save above file with name like message.js.
4. Open command prompt and type bellow command
jjs message.js

We can able to execute the above message.js file


by using java program also.

import javax.script.*;
import java.io.*;
public class Demo{
public static void main(String[] args) throws
Exception{
ScriptEngine ee = new
ScriptEngineManager().getEngineByName("Nashorn");
ee.eval(new FileReader( "C:\\Users\\Ramchandar\\
Desktop\\message.js"));
}
}
Javac Demo.java
Java Demo
Note: we should write in the above program either
“Nashorn” or “nashorn”, otherwise we will get
java.lang.NullPointerException.

ParallelArraySoring:
import java.util.Arrays;
public class ParallelArraySorting {
public static void main(String[] args) {
int[] arr = {5,8,1,0,6,9};
for (int i : arr) {
System.out.print(i+" ");
}
Arrays.parallelSort(arr);
System.out.println("\nArray elements after
sorting");
for (int i : arr) {
System.out.print(i+" ");
}

}
}

ParallelArraySoring by using specific index


positions:
import java.util.Arrays;
public class ParallelArraySorting {
public static void main(String[] args) {
int[] arr = {5,8,1,0,6,9,50,-3};
for (int i : arr) {
System.out.print(i+" ");
}
Arrays.parallelSort(arr,0,4);
System.out.println("\nArray elements after
sorting");
for (int i : arr) {
System.out.print(i+" ");
}
}
}
Working with Date and Time api:
Program on LocalDate class:
import java.time.LocalDate;

public class DateDemo {


public static void main(String[] args) {
//current date
LocalDate ld = LocalDate.now();
System.out.println("ld: "+ld);
String sld = ld.toString();
System.out.println("sld: "+sld);
//our own date
//LocalDate ld1 = LocalDate.of(1987, 12, 16);
LocalDate ld1 = LocalDate.of(2000, 12, 16);
System.out.println("ld1: "+ld1);
boolean b = ld1.isLeapYear();
if(b) {
System.out.println("given year is leap
year");
}
else {
System.out.println("given year is non-
leap year");
}

}
}

Manipulating date and time by using plus and minus


methods of LocalDate:
import java.time.LocalDate;

public class DateDemo {


public static void main(String[] args) {
//current date
LocalDate ld = LocalDate.now();
System.out.println("ld: "+ld);
LocalDate ld1 = LocalDate.MAX;
System.out.println("ld1: "+ld1);
LocalDate ld2 = LocalDate.MIN;
System.out.println("ld2: "+ld2);
LocalDate ld3 = ld.plusDays(1);
System.out.println("ld3: "+ld3);
LocalDate ld4 = ld.plusMonths(2);
System.out.println("ld4: "+ld4);
LocalDate ld5 = ld.plusWeeks(2);
System.out.println("ld5: "+ld5);
LocalDate ld6 = ld.plusYears(2);
System.out.println("ld6: "+ld6);
LocalDate ld7 = ld.minusDays(2);
System.out.println("ld7: "+ld7);
LocalDate ld8 = ld.minusYears(2);
System.out.println("ld8: "+ld8);
LocalDate ld9 = ld.minusMonths(2);
System.out.println("ld9: "+ld9);
LocalDate ld10 = ld.minusWeeks(2);
System.out.println("ld10: "+ld10);
}
}
Program on to get individual years, months, days, weak
from LocalDate:
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.Month;

public class DateDemo {


public static void main(String[] args) {
//current date
LocalDate ld = LocalDate.now();
System.out.println("ld: "+ld);
int year = ld.getYear();
System.out.println("year: "+year);//2018
int month = ld.getMonthValue();
System.out.println("month: "+month);//5
Month m = ld.getMonth();
System.out.println("M: "+m);//MAY
int day = ld.getDayOfMonth();
System.out.println("day: "+day);//11
int dayYear = ld.getDayOfYear();
System.out.println("dayYear: "+dayYear);//131
DayOfWeek dayWeek = ld.getDayOfWeek();
System.out.println("dayWeek:
"+dayWeek);//FRIDAY
//String to LocalDate
//String s = "1987-13-16";//month should be range
String s = "1987-12-16";
LocalDate ld1 = LocalDate.parse(s);
System.out.println("ld1: "+ld1);
//String s1 = "1987-12-32";//day should be range
String s1 = "1987-12-31";
LocalDate ld2 = LocalDate.parse(s1);
System.out.println("ld2: "+ld2);
}
}

Program on LocalDateTime:
import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.Month;

public class DateDemo {


public static void main(String[] args) {
LocalDateTime ldt = LocalDateTime.now();
System.out.println("ldt: "+ldt);
int hour = ldt.getHour();
int min = ldt.getMinute();
int sec = ldt.getSecond();
int nsec = ldt.getNano();
System.out.println("hour: "+hour);
System.out.println("min: "+min);
System.out.println("sec: "+sec);
System.out.println("nsec: "+nsec);
int day = ldt.getDayOfMonth();
System.out.println("day: "+day);
int day1 = ldt.getDayOfYear();
System.out.println("day1: "+day1);
DayOfWeek day2 = ldt.getDayOfWeek();
System.out.println("day2: "+day2);
Month month = ldt.getMonth();
System.out.println("month: "+month);
int mvalue = ldt.getMonthValue();
System.out.println("mvalue: "+mvalue);
int year = ldt.getYear();
System.out.println("year: "+year);
}
}

Program on LocalTime:
import java.time.LocalTime;

public class DateDemo {


public static void main(String[] args) {
LocalTime lt = LocalTime.now();
System.out.println("lt: "+lt);
int h = lt.getHour();
int m = lt.getMinute();
int s = lt.getSecond();
int ns= lt.getNano();
System.out.println("h: "+h);
System.out.println("m: "+m);
System.out.println("s: "+s);
System.out.println("ns: "+ns);
}
}

You might also like