Saturday, 27 June 2015

Enhancements in Java 8 – Java Programming


A.      Lambda Expression
Aka – anonymous function – not bound to an identifier
1.       Used as arguments to higher-order functions
2.       Used to construct the result of a higher-order function that needs to return a function
Functionality that need to be used only for short term – e.g.: ‘closures’ and ‘currying’
a = ['house', 'car', 'bike']
a.sort (lambda x, y: cmp (len(x), len(y)))
print (a)
['car', 'bike', 'house']


B.      Default Methods

Aka – defender function – allows new methods to be added to interfaces without breaking the functionality of existing interface.
Allows interface to use as default in the situation where a concrete class fails to provide implementation for that method.

public interface oldInterface {
    public void existingMethod();
        default public void newDefaultMethod() {
        System.out.println("New default method"
              " is added in interface");
    }
}


How we can use default methods?
ü  Not override the default method and will inherit the default method.
ü  Override the default method similar to other methods we override in subclass.
ü  Redeclare default method as abstract, which force subclass to override it.


C.      Repeating Annotations
Allows same annotations to be used more than once to same declaration or type use. Prior to Java 8, to have repeated annotations, we need to group them into an annotation container.
        @Manufactures({
        @Manufacturer(name =”BMW”),
        @Manufacturer(name = “Range Rover”)
 
        })
        public class Car{
        //code goes in here
        }

Now with Java 8, for repeating annotations, we need not specify an annotation container.
        @Manufacturer(name = “BMW”)
        @Manufacturer(name= “Range Rover”)
        public class Car{
        //code goes in here
}


D.      Type Annotation
Java 7 allowed annotations to be written only on method formal parameters and declarations of packages, classes, methods, fields and local variables. Type annotations are annotations that can be used anywhere we use a type.


Examples:
@NotNull String str1 = ...
@Email String str2 = ...
@NotNull @NotBlank String str3 = ...

Java annotations are used to provide meta data for your Java code. Annotations are used for compiler instructions, build-time instructions and runtime instructions.

Type annotations are provided for stronger type checking.

Java 8 introduces annotations to ‘use’ of types.
·         Class instance creation expression:
new @Intered MyObject();

·         Type cast
mystring = (@NonNull String) str;

·         implements clause
class UnmodifiableList<T> implements
        @Readonly List<@Readonly T> { ... }

·         Thrown exception declaration
void monitorTemperature() throws
        @Critical TemperatureException { ... }




E.       Method References
Shortcuts that can be used anywhere we use lambdas. They are compact and more readable   form of a lambda expression for already written methods.  “::” operator is used for method reference.

Example:
interface IsReferable {
                public void referenceDemo();
                }

class ReferenceDemo {
public static void commonMethod()
{
System.out.println("This method is already defined.");
}

public void implement()
{ // Anonymous class.
IsReferable demoOne = new IsReferable() {
@Override
public void referenceDemo() {
ReferenceDemo.commonMethod();
}
};

demoOne.referenceDemo();

// Lambda implementaion.
IsReferable demo = () -> ReferenceDemo.commonMethod();
demo.referenceDemo();

// Method reference.
IsReferable demoTwo = ReferenceDemo::commonMethod;
demoTwo.referenceDemo();
}
}


F.       Type Interface - Generics
It is possible to infer the generic types from method signatures when passing a constructor as a parameter of a method. Java 7 does not use ‘target typing’, but Java 8 does. Target typing is a language feature wherein the type of the variable in which a result is to be stored influences the type of the computation.


Target typing example:
long MICRO_SECONDS_IN_DAY = 24 × 60 × 60 × 1000 × 1000; à Java 7 does not return what is        expected.

Type interface example:
public class TypeInference {
  public int getDictionarySize(Map<String, String> theDict) {
    return theDict.size();
  }
}


@Test
public void emptyDictionarySizeShouldBeZero() {
  TypeInference testObj = new TypeInference();

  Map<String, String> dict = new HashMap<>();

  int expected = 0;
  int actual = testObj.getDictionarySize(dict);

  assertEquals("Size is incorrect!", expected, actual);
}


@Test
public void emptyDictionarySizeShouldBeZero2() {
  TypeInference testObj = new TypeInference();

  int expected = 0;
  int actual = testObj.getDictionarySize(new HashMap<>());  //Java 7: Compile Error.
                                                            //Java 8: Better Type Inference

  assertEquals("Size is incorrect!", expected, actual);
}



G.     Method parameter reflection
We can obtain the names of the formal parameters of any method constructor with the method java.lang.reflect.Executable.getParameters. However, .class files do not store formal parameter names by default. To store formal parameter names in a particular .class file, and thus enable the Reflection API to retrieve formal parameter names, compile the source file with the -parameters option of the javac compiler.



H.     Collections – The new ‘java.util.stream’ package
Classes in the new java.util.stream package provide a Stream API to support functional-style operations on streams of elements. The Stream API is integrated into the Collections API, which enables bulk operations on collections, such as sequential or parallel map-reduce transformations.

Example:
                    int sum = widgets.stream()
                      .filter(b -> b.getColor() == RED)
                      .mapToInt(b -> b.getWeight())
                      .sum();

Here we use widgets, a Collection<Widget>, as a source for a stream, and then perform a filter-map-reduce on the stream to obtain the sum of the weights of the red widgets.

The key abstraction introduced in this package is stream. The classes Stream, IntStream, LongStream, and DoubleStream are streams over objects and the primitive int, long and double types. Streams differ from collections in several ways:

No storage. A stream is not a data structure that stores elements; instead, it conveys elements from a source such as a data structure, an array, a generator function, or an I/O channel, through a pipeline of computational operations.

Functional in nature. An operation on a stream produces a result, but does not modify its source.

Laziness-seeking. Many stream operations, such as filtering, mapping, or duplicate removal, can be implemented lazily, exposing opportunities for optimization.

Possibly unbounded. While collections have a finite size, streams need not.

Consumable. The elements of a stream are only visited once during the life of a stream. Like an Iterator, a new stream must be generated to revisit the same elements of the source.

Stream operations are divided into intermediate and terminal operations, and are combined to form stream pipelines. A stream pipeline consists of a source (such as a Collection, an array, a generator function, or an I/O channel); followed by zero or more intermediate operations such as Stream.filter or Stream.map; and a terminal operation such asStream.forEach or Stream.reduce.




I.        Collections - Performance Improvement for HashMaps with Key Collisions

Hash bins containing a large number of colliding keys improve performance by storing their entries in a balanced tree instead of a linked list. This JDK 8 change applies only to HashMap, LinkedHashMap, and ConcurrentHashMap.

In rare situations, this change could introduce a change to the iteration order of HashMap and HashSet. A particular iteration order is not specified for HashMap objects - any code that depends on iteration order should be fixed.

Java 8 is on average 20% faster than Java 7 in simple HashMap.get(). When a bucket becomes too big (currently: TREEIFY_THRESHOLD = 8), HashMap dynamically replaces it with an ad-hoc implementation of tree map.



References:


No comments:

Post a Comment