1)
Interface changes:
Java 8 interface changes include static
methods and default methods in interfaces. Prior to Java 8, we could have only
method declarations in the interfaces. But from Java 8, we can have default
methods and static
method
implementaions
Default
Method:
For
creating
a default method in java interface, we need to use “default”
keyword with the method
signature
public interface Interface1 {
void method1(String str);
default void
log(String str){
System.out.println("I1
logging::"+str);
}
}
Notice that log(String str) is
the default method in the Interface1. Now when a class will implement
Interface1, it is not mandatory to provide implementation for default methods
of interface. This feature will help us in extending interfaces with additional
methods, all we need is to provide a default implementation.
•Java
interface default methods will help us in removing base implementation classes,
we can provide default implementation and the implementation classes can chose
which one to override.
•Java
interface default methods will help us in extending interfaces without having
the fear of breaking implementation classes.
Java Interface
Static Method
•Java
interface static method is similar to default method except that we can’t
override them in the implementation classes. This feature helps us in avoiding
undesired results in
case of
poor implementation in implementation classes.
•Java
interface static method is part of interface, we can’t use it for
implementation class objects.
•Java
interface static methods are good for providing utility methods,for example
null check, collection sorting etc.
•Java
interface static method helps us in providing security by not allowing
implementation classes to override them.
•We
can’t define interface static method for Object class methods, we will get
compiler error as “This static method cannot hide the instance method from
Object”. This is because it’s not allowed in java, since Object is the base
class for all the classes and we can’t have one class level static method and
another instance method with same signature.
2.Java Functional Interfaces
•An
interface
with exactly one abstract method is known as Functional Interface.
A
new annotation @FunctionalInterface has
been introduced to mark an interface as Functional Interface. @FunctionalInterface
annotation is a facility to avoid accidental addition of abstract methods in
the functional interfaces. It’s optional but good practice to use it.
•Static
methods, by definition, are not abstract – @FunctionalInterface can
have zero or more static methods
Ex- 1 Interface Predicate<T>
Type Parameters:T -
the type of the input to the predicate
This is a functional interface and can
therefore be used as the assignment target for a lambda expression or method
reference. It
has a abstract method test(T t ) and other methods
Parameters: t -
the input argument
Returns:true if
the input argument matches the predicate, otherwise false
Ex 2: Interface Runnable
This is a functional interface and can
therefore be used as the assignment target for a lambda expression or method
reference.
3.Lamda Expressions
•One
of the major benefits of functional interface is the possibility to use lambda
expressions to
instantiate them. We can instantiate an interface with anonymous class but
the code looks bulky.
•Runnable
r = new Runnable(){
@Override public void run() {
System.out.println("My
Runnable");
}
};
Since functional interfaces have only one
method, lambda expressions can easily provide the method implementation. We
just need to provide method arguments and business logic. For example, we can
write above implementation using lambda expression as:
•Runnable
r1 = () -> { System.out.println("My
Runnable"); };
lambda
expressions are means to create anonymous classes of functional interfaces
easily. There are no runtime benefits of using lambda expressions
4.
Java Time API
•It
has always been hard to work with Date, Time and Time Zones in java. There was
no standard approach or API in java for date and time in Java. One of the nice
addition in Java 8 is the java.time package that will streamline the process of
working with time in java.
•Just
by looking at Java Time API packages. It has some sub-packages java.time.format that
provides classes to print and parse dates and times and java.time.zone provides
support for time-zones and their rules.
5.forEach() method in Iterable
interface
•Whenever
we need to traverse through a Collection, we need to create
an Iterator whose whole purpose is to iterate over and then we have
business logic in a loop for each of the elements in the Collection. We might
get ConcurrentModificationException if
iterator is not used properly.
•Java
8 has introduced forEach method in java.lang.Iterable interface
so that while writing code we focus on business logic only. forEach method
takes java.util.function.Consumer object
as argument, so it helps in having our business logic at a separate location
that we can reuse. Let’s see forEach usage with simple example.
Ex -public
static void main(String[] args) {
//creating sample Collection
List<Integer> myList =
new ArrayList<Integer>();
for(int i=0; i<10;
i++)
myList.add(i);
//traversing using Iterator
Iterator<Integer>
it = myList.iterator();
while(it.hasNext()){
Integer i = it.next();
System.out.println("Iterator
Value::"+i);
}
//traversing through forEach
method of Iterable with
anonymous class
myList.forEach(new Consumer<Integer>()
{
public void accept(Integer t) {
System.out.println("forEach
anonymous class Value::"+t);
}
});
//traversing with Consumer interface
implementation MyConsumer
action = new MyConsumer(); myList.forEach(action);
}
•//Consumer
implementation that can be reused
class MyConsumer implements Consumer<Integer>{
public void accept(Integer t) {
System.out.println("Consumer
impl
Value::"+t);
}
}
•The
number of lines might increase but forEach method helps in having the logic for
iteration and business logic at separate place resulting in higher separation
of concern and cleaner code.
6.Concurrency API
improvements
Some
important
concurrent API enhancements are
•ConcurrentHashMap compute(),
forEach(), forEachEntry(), forEachKey(), forEachValue(),
merge(), reduce() and search() methods.
•CompletableFuture that
may be explicitly completed (setting its value and status).
•Executors newWorkStealingPool() method
to create a work-stealing thread pool using all available processors as its
target parallelism level.
7.Nashorn
Java Script Engine
•Nashorn
engine lets you integrate Java with JavaScript
on a highly performant virtual machine. It is also incredibly compliant with
the ECMAScript standard for JavaScript
•You
can run JavaScript through the jjs interpreter, or from Java via the
scripting API.
•Use
the predefined JavaScript objects for the most common packages, or the Java.type
function to access any package.
•
Beware of
intricacies in the conversion of strings and numbers between JavaScript and
Java.
•JavaScript
offers
a convenient syntax for working with Java lists and maps, as well as JavaBeans
properties.
•You
can
convert JavaScript functions to Java interfaces in a way that is very similar
to using lambda expressions.
•You
can
extend Java classes and implement Java interfaces in JavaScript, but there are
limitations.
•Nashorn has
good support for writing shell scripts in JavaScript.
•You
can
write JavaFX
programs in JavaScript, but the integration is not as good as it might be
Running
Java script from Java command line tool
•To
start run tool jjs
,make sure java path is set
•> jjs
jjs> 'Hello, World' Hello, World
•You
can define functions and call them
• jjs>
function factorial(n) { return n <= 1 ? 1 : n * factorial(n - 1) }
function factorial(n)
{ return n <= 1 ? 1 : n * factorial(n - 1) }
jjs> factorial(10) 3628800
Running
Nashorn from
Java
•To
run a script, you need to get a ScriptEngine
object. If the engine is registered, you can simply get it by name. Java 8
includes an engine with name "nashorn".
•Here is
how to use it:
public
class Test {
public static void main(String[] args)
throws ScriptException
{
ScriptEngineManager manager
= new
ScriptEngineManager();
ScriptEngine engine
= manager.getEngineByName("nashorn");
Object result
= engine.eval("'Hello,
World!'.length");
System.out.println(result);
}
}
8.Collection
Improvements:
Class/Interface
l
8.1
How to use removeIf
method
•The
removeIf()
method is used to remove all of the elements of this collection that satisfy
the given predicate. Errors or runtime exceptions are thrown during iteration
or by the predicate are
relayed
to the caller.
Ex:
class SamplePredicate<t> implements Predicate<t>{
T varc1;
public boolean test(T varc){
if(varc1.equals(varc)){
return true;
}
return false;
}
}
public class test {
public static void main(String[] args) {
ArrayList<String> color_list;
SamplePredicate<String> filter;
color_list = new ArrayList<> ();
filter = new SamplePredicate<> ();
filter.varc1 = "White";
color_list.add("White");
color_list.add("Black");
color_list.add("Red");
color_list.add("White");
color_list.add("Yellow");
color_list.add("White");
System.out.println("List of Colors");
System.out.println(color_list);
// Remove all White colors from color_list
color_list.removeIf(filter);
System.out.println("Color list, after removing White colors :");
System.out.println(color_list);
}
}
Output: Color list,
after removing White colors :
[Black, Red, Yellow]
8.2
How to use replaceAll
method of list
•replaceAll(UnaryOperator<E>
operator)
The replaceAll() method is used to replace each element
of this list with the result of applying the operator to that element. Errors
or
runtime exceptions are thrown by the ope
rator are relayed to the caller.
•Ex-class MyOperator<T> implements UnaryOperator<T>{
T varc1;
public T apply(T varc){
return varc1;
}
}
public class Test
{
public
static void main(String[] args) {
ArrayList<String>
color_list;
MyOperator<String>
operator;
color_list = new
ArrayList<> ();
operator = new MyOperator<> ();
operator.varc1 = "White";
color_list.add("White");
color_list.add("Black");
color_list.add("Red");
color_list.add("White");
color_list.add("Yellow");
color_list.add("White");
System.out.println("List
of Colors");
System.out.println(color_list);
//
Replace all colors with
White color
color_list.replaceAll(operator);
System.out.println("Color
list, after replacing all colors
with White color
:");
System.out.println(color_list);
}
}
Output:
List of Colors
[White,
Black, Red, White, Yellow, White]
Color list, after replacing all colors
with White color
:
[White, White, White, White, White, White]
8.3
Spliterator
•An
object for traversing and partitioning elements of a source. The source of
elements covered by a Spliterator could be, for example, an array, a Collection, an
IO channel, or a generator function.A Spliterator may traverse elements
individually (tryAdvance()) or
sequentially in bulk (forEachRemaining()).
Methods:
•Returns
an
estimate of the number of elements that would be encountered by a forEachRemaining(java.util.function.Consumer<?
super T>) traversal,
or returns Long.MAX_VALUE if
infinite, unknown, or too expensive to compute
•If
a
remaining element exists, performs the given action on it, returning true;
else returns false.
•boolean trySplit()
:If this spliterator can
be partitioned, returns a Spliterator covering elements, that will, upon return
from this method, not be covered by this Spliterator.
8.4
forEachRemaining
method
•This
method is found in Iterator and Spliterator both
interfaces
It Performs the
given action for each remaining element until all elements have been processed
or the action throws an exception. Actions are performed in the order of
iteration, if that order is specified. Exceptions thrown by the action are
relayed to the caller.
•Implementation Requirements:
The default
implementation behaves as if:
while (hasNext())
action.accept(next());
Implementation Requirements: The default
implementation repeatedly invokes tryAdvance(java.util.function.Consumer<?
super T>) until
it returns false. It should be overridden whenever possible.
Performs the given action for each
remaining element, sequentially in the current thread, until all elements have
been processed or the action throws an exception. If this Spliterator is ORDERED,
actions are performed in encounter order. Exceptions thrown by the action are
relayed to the caller.