Java Unit 3 Notes New Fetures Part 1
Java Unit 3 Notes New Fetures Part 1
Java programming language is always a leading programming language, from the last 20 years Java is
the winner is all aspects, but nowadays functional programming concepts are on air. That’s why
Python, Ruby, NodeJS, and other programming languages that support functional programming was
taking lead from Java, so to take lead again, Java introduced new striking features in 1.8 version that
highly support functional programming in Java. It does not mean, Java does not object orient now, it
is object-oriented but support functional programming being object-oriented.
If the programmer wants to add new service or logic in the interface without doing modification on
the implementation class of interface, then now from Java version 1.8 he/she can use default methods
in the interface.
interface Message {
public abstract void msg ();
}
public static void main (String [] args)
m1.msg();
m1.msg2();
interface Message {
public abstract void msg ();
}
public static void main (String [] args)
m1.msg();
m1.msg2();
Message.msg3();
Functional Interface
Functional Interface is new concepts in Java after version 1.8, It is the core striking features in version
1.8, because of a functional interface, other features of java 1.8 exists like Lambda expression, method
references, Java.util.function packages and Java Stream API. All these features are 100% dependent
on functional interface. This functional interface concept brings again Java to stand strongly in front
of the functional programming supported languages like Python, Ruby, etc.
It is not a new kind of interface; it is an old one but with some restrictions. An Interface, which allows
only one abstract method declaration with @FunctionalInterface annotation is called Functional
Interface. In Function Interfaces, more than one default, or static method is allowing and you can also
write java.lang.Object class methods, but more than one abstract method is not allowed.
@FunctionalInterface
interface Message {
public abstract void msg ();
m1.msg();
}
Lambda Expression
Lambda expression is a great feature in Java 1.8 version. It helps the programmer to write less code
with functional programming features. Lambda Expression is just an anonymous or nameless function
declaration, it means the function which doesn’t have a name, return type, and access modifiers.
Lambda expression function with one parameter can be declared 3 ways as explained below.
Type 1 declaration:
Type 2 declaration:
(msg)->System.out.println(msg);
Type 3 declaration:
msg->System.out.println(msg);
System.out.println(msg);
}
C) Lambda expression or nameless function declaration with more than one parameters
Lambda expression function with more than one parameter can be declared only 1 way as
explained below.
(int num1, int num2) -> System.out.println(“Sum of two number is=” + (num1+num2));
D) Lambda expression or nameless function declaration with multiple statements. If more than
one statements present than we have to enclose inside curly braces. If one statement
present, then curly braces are optional as shown above also.
Lambda expression function with more than one parameter can be declared only 1 way as
explained below.
Int sum=num1+num2;
Int sum=num1+num2;
@FunctionalInterface
interface Message
{
}
public class Test
//Interface implementation using Anonymous Inner Class: - Order Method in Java 1.7 or earlier
@Override
public void msg()
{
m1.msg();
//Interface implementation using Lambda Express: - New method in Java 1.8 or later
m2.msg();
Method References
The mapping of Function Interface method to the specified method by using “::” (double colon)
operator is called Method Referencing. This specified method can be either a static or instance
method. But there is a condition, Functions Interface method and specified method should have same
argument types, except this the remaining things like return type, method name, access modifier is
not required to match.
The syntax for Method References:
Classname::methodName
Objectname::methodName
@FunctionalInterface
interface Message
class DisplayMessage
Message m1 =dm::display();
m1.msg();
Message m2 =DisplayMessage::display2();
m2.msg();
Constructor References
The mapping of the constructor to the specified method by using “::” (double colon) operator is called
Constructor Referencing.
Classname::new
@FunctionalInterface
interface Message
class DisplayMessage
public DisplayMessage()
Message m1 =DisplayMessage::new;
m1.msg();
}
Use of Package java.util.function
This java.util.function package provides standard library-based functional interfaces for common
requirements with their corresponding lambda expression, which can be used by the programmer in
his code instead of creating brand new functional interfaces.
List of most commonly used Functional Interfaces under this package are:
1. Function
This interface has one function apply (), this function takes one input parameter as T and
return value as R after performing some kind of operation on the input parameter.
Structure of Function interface:
@FunctionalInterface
public interface Function <T, R> {
R apply (T t);
}
This T and R may have any type of value like Integer, Float, Double, String, etc.
Let’s understand the use of it by given example:
import java.util.function.Function;
System.out.println(half.apply(10));
2. BiFunction
This interface also has one function apply (), this function takes two input parameters as T and
U and returns a value as R after performing some kind of operation on given input parameters.
Structure of BiFunction interface:
@FunctionalInterface
public interface BiFunction <T, U, R> {
R apply (T t, U u);
}
This T, U, and R may have any type of value like Integer, Float, Double, String, etc.
Let’s understand the use of it by given example:
import java.util.function.BiFunction;
// This function takes two numbers and returns sum of these two number
BiFunction<Integer, Integer, Integer> sum = (Integer num1, Integer num2) -> num1+num2;
3. UnaryOperator
This interface also has one function apply(), this function takes one input parameter and
returns a value of the same input type after performing some kind of operation on the given
input parameter.
Structure of Function interface:
@FunctionalInterface
public interface UnaryOperator <T> {
T apply (T t);
}
This T may have any type of value like Integer, Float, Double, String, etc.
Let’s understand the use of it by a given example:
import java.util.function.*;
4. Consumer
This interface has one function accept (), this function only takes one input parameter, but
does not return any value.
Structure of Function interface:
@FunctionalInterface
public interface Consumer <T> {
void accept (T t);
}
This T may have any type of value like Integer, Float, Double, String, etc.
Let’s understand the use of it by a given example:
import java.util.function.*;
};
square.accept(10);
5. BiConsumer
This interface has one function accept(), this function takes two input values for performing
some operations and does not return any value.
Structure of Function interface:
@FunctionalInterface
public interface BiConsumer <T, R> {
void accept (T t, R r);
}
This T and R may have any type of value like Integer, Float, Double, String, etc.
Let’s understand the use of it by a given example:
import java.util.function.*;
// This function takes two input value and does not return any value
sum.accept(30,40);
6. Supplier
This interface has one function get(), this function does not take any parameter, but return
value after performing a given task of the function.
Structure of Function interface:
@FunctionalInterface
public interface Supplier<T> {
T get ();
}
This T may have any type of value like Integer, Float, Double, String, etc.
Let’s understand the use of it by a given example:
import java.util.function.*;
// This function does not take any input value, but return value
Supplier<String> s1 = () -> {
String name=scan.nextLine();
return name;
};
1. Use of Stream API map () function to get square of each number present in ArrayList.
import java.util.function.*;
li.add(10);
li.add(20);
li.add(30);
li.add(40);
List<Integer> ll =li.stream().map((x)->x*x).collect(Collectors.toList());
Explanation of code:
This stream () function converts all list elements into a stream, then map () function perform a square
operation on each element of a list, and then at last collect () function again convert all stream
elements to list elements.
2. Use of Stream API filer () and map () function to get square of selected number present in
ArrayList.
import java.util.function.*;
li.add(10);
li.add(11);
li.add(30);
li.add(15);
List<Integer> ll =li.stream().
filter((x)->x%2==0).
map((x)->x*x).
collect(Collectors.toList());
Explanation of code:
This stream () function converts all list elements into stream, then filter () function select only even
numbers the list as per the given condition for even number, then map () function perform a square
operation on filtered even number of the list, and then at last collect () function again convert all
stream elements to list elements.
3. Use of Stream API distinct(), limit(), peek() and count() function to get square of selected
number present in ArrayList.
import java.util.function.*;
li.add(10);
li.add(10);
li.add(30);
li.add(30);
li.add(20);
li.add(20);
li.add(50);
li.add(60);
li.stream().distinct().limit(3).
count();
}
Explanation of code:
This stream () function converts all list elements into a stream, then distinct () function select unique
numbers from the list, then limit () function select first numbers from the list as per parameter
assigned in limit() function like 3 in above example. then peek() function perform a task on selected
numbers from limit() function and then count function display selected numbers of list line by line.
There are lot more functions in this Stream API, like anyMatch(), allMatch(), noneMatch(), findAny(),
findFirst(), toArray(), reduse(), max(), min(), and etc. Details of all these functions are lot of the scope
of this app.
1. Stream does not store the elements; it simply performs the aggregate operations on data.
2. The aggregate operations that perform on the collection array or any other data source do
not change the data of the source, they simply return new steam of data.
3. All the stream operations are lazy which means they are not executed until they are needed.