Showing posts with label New in java. Show all posts
Showing posts with label New in java. Show all posts

Sunday, 31 August 2014

JDK 8 Features

Lambda Expressions

The biggest new feature of Java 8 is language level support for lambda expressions.

The point of lambda is to be able to pass some code to a method rather than objects. Until java 8, the way to achieve this in java would be to use callbacks. The issue with callbacks is that it leads to verbose code. Like you would write 5 lines of code when the real job is in 1 of these 5 lines.

The other scenario is when dealing with group of data to execute specific algorithm on it.
Here are few code examples of lambda expressions usage.

Inner classes

An example of what you would do today:
btn.setOnAction(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent event) {
        System.out.println("Hello World!");
    }
});
With lambda in java 8 you just have:
btn.setOnAction(
    event -> System.out.println("Hello World!")
);

Method references

Two examples with static and non statics methods.
Statics method:
public class Utils {
    public static int compareByLength(String in, String out){
        return in.length() - out.length();
    }
}

public class MyClass {
    public void doSomething() {
        String[] args = new String[] {"microsoft","apple","linux","oracle"}
        Arrays.sort(args, Utils::compareByLength);
    } 
}
Non statics method:
public class MyClass implements Comparable<MyObject> {
    
    @Override
    public int compareTo(MyObject obj) {return ...}

    public void doSomething() {
        MyObject myObject = new MyObject();
        Arrays.sort(args, myObject::compareTo);
    } 
}

Date/Time changes

The Date/Time API is moved to java.time package and Joda time format is followed. Another goodie is that most classes are Threadsafe and immutable.

Stream Collection Types (java.util.stream)

A stream is a iterator that allows a single run over the collection it is called on. You can use streams to perform functional operations like filer or map/reduce over collections which can be streamed as individual elements using Stream objects. Streams can run sequentially or parallely as desired. The parallel mode makes use of fork/join framework and can leverage power of multiple cores.

Other – (nice to have) Changes

String.join() method is a welcome addition as a lot of self created utility classes are created instead. So, the following example

String abc= String.join(" ", "Java", "8");
Will get evaluated as “Java 8″.

Annotation on Java Types

Base64 Encoding/Decoding


Defines a standard API for BASE64 Encoding and Decoding
java.util.Base64.Encoder
java.util.Base64.Decoder

This feature means we don’t have to search around for other implementations, making things a bit easier.

Encoding

String base64 = Base64.getEncoder().encodeToString("string to encode".getBytes("utf-8"));

Decoding

byte[] asBytes = Base64.getDecoder().decode("your base 64 string");

Functional interfaces

A functional interface is the one that defines exactly one abstract method. We have for instance “java.lang.Runnable” defining the run abstract method:
public abstract void run();
We can still add as many default methods (non abstract) as we like.
While defining a new functional interface, we will have to define the new annotation “@FunctionalInterface”. This will allow us to block bad usages of functional interfaces as it will not compile if used improperly with the new annotation.

Remove the Permanent Generation

That is definitely a big one. The Permanent Generation (PermGen) space has completely been removed and is kind of replaced by a new space called Metaspace.
The consequences of the PermGen removal is that obviously the PermSize and MaxPermSize JVM arguments are ignored and you will never get a java.lang.OutOfMemoryError: PermGen error.
However that doesn't mean you won't have to worry about the class metadata memory footprint and it does not eliminate class and classloader memory leaks.

Most allocations for the class metadata are now allocated out of native memory and classes used for describing the class metadata are removed. The Metaspace will dynamically re-size depending on the application demand at runtime. There is obviously some garbage collection involved but I don't think that there is much to worry about here unless you have a problem of classes, classloaders memory leak or an inadequate sizing of the metaspace (as you can specify the maximum metaspace capacity with MaxMetaspaceSize otherwise it is limited by the amount of available native memory).

Small VM


The goal here is to have a VM which is no more than 3Mb by allowing some features to be excluded at build time. The motivation behind this is to allow the JVM to run on small devices which have very strict static and dynamic memory-footprint requirements.

Parallel array sorting

Java 8 introduces a new API for sorting: Arrays#parallelSort.

Arrays#parallelSort uses Fork/Join framework introduced in Java 7 to assign the sorting tasks to multiple threads available in the thread pool.



References:
https://leanpub.com/whatsnewinjava8/read
http://java.dzone.com/articles/java-8-permgen-metaspace
http://java.dzone.com/articles/introduction-functional-1

JDK 7 Features

switch on String

Before JDK 7, only integral types can be used as selector for switch-case statement. In JDK 7, you can use a String object as the selector. For example,

String day = "SAT";
switch (day) {
   case "MON": System.out.println("Monday"); break;
   case "TUE": System.out.println("Tuesday"); break;
   case "WED": System.out.println("Wednesday"); break;
   case "THU": System.out.println("Thursday"); break;
   case "FRI": System.out.println("Friday"); break;
   case "SAT": System.out.println("Saturday"); break;
   case "SUN": System.out.println("Sunday"); break;
   default: System.out.println("Invalid");
}

String.equals() method is used in comparison, which is case-sensitive.

Binary Literals with prefix "0b"

In JDK 7, you can express literal values in binary with prefix '0b' (or '0B') for integral types (byte, short, int and long), similar to C/C++ language. Before JDK 7, you can only use octal values (with prefix '0') or hexadecimal values (with prefix '0x' or '0X').

BEFORE:

public void testBinaryIntegralLiterals(){
 
        int binary = 8;
 
        if (binary == 8){
            System.out.println(true);
        } else{
            System.out.println(false);
        }
}

AFTER:

public void testBinaryIntegralLiterals(){
 
        int binary = 0b1000; //2^3 = 8
 
        if (binary == 8){
            System.out.println(true);
        } else{
            System.out.println(false);
        }
}

Underscore for Numeric Literals

In JDK 7, you could insert underscore(s) '_' in between the digits in an numeric literals (integral and floating-point literals) to improve readability. For example,

int anInt = 0b10101000_01010001_01101000_01010001;
double aDouble = 3.1415_9265;
float  aFloat = 3.14_15_92_65f;

Catching Multiple Exception Types

In JDK 7, a single catch block can handle more than one exception types. For example, before JDK 7, you need two catch blocks to catch two exception types although both perform identical task:
try {
   ......
} catch(ClassNotFoundException ex) {
   ex.printStackTrace();
} catch(SQLException ex) {
   ex.printStackTrace();
}
In JDK 7, you could use one single catch block, with exception types separated by '|'.
try {
   ......
} catch(ClassNotFoundException|SQLException ex) {
   ex.printStackTrace();
}

The try-with-resources Statement a.k.a Automatic Resource Management

For example, before JDK 7, we need to use a finally block, to ensure that a resource is closed regardless of whether the try statement completes normally or abruptly. The code is messy!
import java.io.*;
// Copy from one file to another file character by character.
// Pre-JDK 7 requires you to close the resources using a finally block.
public class FileCopyPreJDK7 {
   public static void main(String[] args) {
      BufferedReader in = null;
      BufferedWriter out = null;
      try {
         in  = new BufferedReader(new FileReader("in.txt"));
         out = new BufferedWriter(new FileWriter("out.txt"));
         int charRead;
         while ((charRead = in.read()) != -1) {
            System.out.printf("%c ", (char)charRead);
            out.write(charRead);
         }
      } catch (IOException ex) {
         ex.printStackTrace();
      } finally {            // always close the streams
         try {
            if (in != null) in.close();
            if (out != null) out.close();
         } catch (IOException ex) {
            ex.printStackTrace();
         }
      }
 
      try {
         in.read();   // Trigger IOException: Stream closed
      } catch (IOException ex) {
         ex.printStackTrace();
      }
   }
}
JDK 7 introduces a try-with-resources statement, which ensures that each of the resources in try(resources) is closed at the end of the statement. This results in cleaner codes.
import java.io.*;
// Copy from one file to another file character by character.
// JDK 7 has a try-with-resources statement, which ensures that
// each resource opened in try() is closed at the end of the statement.
public class FileCopyJDK7 {
   public static void main(String[] args) {
      try (BufferedReader in  = new BufferedReader(new FileReader("in.txt"));
           BufferedWriter out = new BufferedWriter(new FileWriter("out.txt"))) {
         int charRead;
         while ((charRead = in.read()) != -1) {
            System.out.printf("%c ", (char)charRead);
            out.write(charRead);
         }
      } catch (IOException ex) {
         ex.printStackTrace();
      }
   }
}

Type Inference for Generic Instance Creation

import java.util.*;
public class JDK7GenericTest {
   public static void main(String[] args) {
      // Pre-JDK 7
      List<String> lst1 = new ArrayList<String>();
      // JDK 7 supports limited type inference for generic instance creation
      List<String> lst2 = new ArrayList<>();
 
      lst1.add("Mon");
      lst1.add("Tue");
      lst2.add("Wed");
      lst2.add("Thu");
 
      for (String item: lst1) {
         System.out.println(item);
      }
 
      for (String item: lst2) {
         System.out.println(item);
      }
   }
}

Fork Join framework in Java 7


Fork join framework exists even before Java 7 but as a separate JSR. It has been added as new feature in Java 7 to make it part of standard Java 7 core library. Fork join framework allows you to write code which can take advantage of multiple cores present in modern servers. 

Fork-join functionality is achieved by ForkjoinTask object, it has two method fork() and join () Method.
  • The fork() method allows  a new ForkJoinTask to be launched from an existing one.
  • The join() method allows a ForkJoinTask to wait for the completion of another one.
Again ForkjoinTask object has been of two types: RecursiveAction and RecursiveTask which is more specialized form of this instance. While RecursiveAction represent executions that do not yield a return value, Instances of RecursiveTask yield return values.