ServiceNow connector deployment guide 1.0.0.0

Java 8 – Functional Programming And Much More

Java 8 Features
Oracle released a new version of Java as Java 8 in March 18, 2014. It was a revolutionary release of the Java for software development platform. It includes various upgrades to the Java programming, JVM, Tools and libraries.
Java 8 Programming Language Enhancements
Java 8 provides following features for Java Programming:
• Lambda expressions,
• Functional interfaces,
• Method references,
• Stream API,
• Default methods,
• Static methods in interface,
• Date/Time API
• ForEach() method,
• Base64 Encode Decode,
• Parallel array sorting,
• Nashorn JavaScript Engine,
• Optional class,
• StringJoiner class
• JDBC Enhancements etc.

 Java Lambda Expressions
1. What is a lambda expression in Java?
Lambda expression is a new and important feature of Java which was included in Java SE 8.
In programming, a Lambda expression (or function) is just an anonymous function, i.e., a function with no name and without being bounded to an identifier.
In other words, lambda expressions are nameless functions given as constant values, and written exactly in the place where it’s needed, typically as a parameter to some other function.
It provides a clear and concise way to represent one method interface using an expression. It is very useful in the collection library. It helps to iterate, filter and extract data from the collection.
The Lambda expression is used to provide the implementation of an interface which has a functional interface. It saves a lot of code. In case of lambda expression, we don’t need to define the method again for providing the implementation. Here, we just write the implementation code.

1.1 Why use Lambda Expression
1. To provide the implementation of Functional interface.
2. Less coding.

1.2 Java Lambda Expression Syntax
1. (argument-list) -> {body}
Java lambda expression is consisted of three components.
1) Argument-list: It can be empty or non-empty as well.
2) Arrow-token: It is used to link arguments-list and body of expression.
3) Body: It contains expressions and statements for lambda expression.

A typical lambda expression syntax will be like this:
(x, y) -> x + y // This function takes two parameters and return their sum.
Now based on type of x and y, method may be used in multiple places. Parameters can match to int, or Integer or simply String also. Based on context, it will either add two integers or concat two strings.
Syntax:
The other possible syntaxes of a lambda expression are:
1. (parameters) -> expression
2. (parameters) -> { statements; }
3. () -> expression

1.3 Features of Lambda Expressions
Let’s identify some features of lambda expression:
1. A lambda expression can have zero, one or more parameters.
2. The type of the parameters can be explicitly declared or it can be inferred from the context.
3. Multiple parameters are enclosed in mandatory parentheses and separated by commas. Empty parentheses are used to represent an empty set of parameters.
4. When there is a single parameter, if its type is inferred, it is not mandatory to use parentheses. e.g. a -> return a*a.
5. The body of the lambda expressions can contain zero, one or more statements.
6. If body of lambda expression has single statement curly brackets are not mandatory and the return type of the anonymous function is the same as that of the body expression. When there is more than one statement in body than these must be enclosed in curly brackets.

1.4 Java Lambda Expression Examples:

Example 1: Java Lambda Expression with no parameter
interface Sayable
{
public String say();
}
public class LambdaExpressionExample
{
public static void main(String[] args)
{
Sayable s = () -> { return “Hello”; };
System.out.println(s.say());
}
}
Output :- Hello
Example 2: Java Lambda Expression with single parameter
interface MyFunctionalInterface
{
public int incrementByFive(int a);
}
public class LambdaExpressionExample
{
public static void main(String args[])
{
MyFunctionalInterface f = (num) -> num+5;
System.out.println(f.incrementByFive(22));
}
}
Output :- 27
Example 3: Java Lambda Expression with Multiple Parameters
interface Addable
{
int add(int a,int b);
}

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

Addable a = (x,y)->(x+y);
System.out.println(a.add(10,20));

}
}
Output :- 30

Example 4: Iterating collections using foreach loop
import java.util.ArrayList;
import java.util.List;

public class Demo
{
public static void main(String[] args)
{
List list=new ArrayList();
list.add(“Rick”);
list.add(“Negan”);
list.add(“Daryl”);
list.add(“Glenn”);
list.add(“Carl”);
list.forEach(

(names)->System.out.println(names)
);
}
}

Before going deep in relation between lambda expressions and java programming, you must know about functional interfaces as well. It is just too important.

 Java Functional Interfaces
An Interface that contains exactly one abstract method is known as functional interface. It can have any number of default, static methods but can contain only one abstract method. It can also declare methods of object class.
Functional Interface is also known as Single Abstract Method Interfaces or SAM Interfaces. It is a new feature in Java, which helps to achieve functional programming approach.
Java 8, enforces the rule of single responsibility by marking these interfaces with a new annotation i.e. @FunctionalInterface.

Example 1: Creating our own Functional Interface
interface SampleInterface
{
void msg(String msg);
}
public class Test implements SampleInterface
{
public void msg(String msg)
{
System.out.println(msg);
}
public static void main(String[] args) {
Test test = new Test();
test.msg(“Hello World”);
}
}

Example 2: Using predefined functional interface
Java provides predefined functional interfaces to deal with functional programming by using lambda and method references.
Predicate :-
Predicate is a functional interface which represents a predicate (boolean-valued function) of one argument. It is defined in the java.util.function package and contains test() a functional method.
import java.util.function.Predicate;
public class PredicateInterfaceExample
{
public static void main(String[] args)
{
Predicate pr = a -> (a > 18); // Creating predicate
System.out.println(pr.test(10)); // Calling Predicate method
}
}

Function:-
It is a functional interface. It is used to refer method by specifying type of parameter. It returns a result back to the referred function.

import java.util.function.Function;
public class FunctionInterfaceExample {

public static void main(String[] args)
{
Function<Integer, Integer> function = i ->i*i;
// Function interface referring to a method

System.out.println(function.apply(4)); // Calling Function interface method
}
}

Consumer :- It is a functional interface defined in java.util.function package. It contains an abstract accept() method.
The Consumer Interface accepts a single argument and does not return any result.
import java.util.function.Consumer;

public class Demo
{

public static void main(String[] args)
{

Consumer consumer1 = str -> System.out.println(str);
// Referring method to String type Consumer interface

consumer1.accept(“John”); // Calling Consumer method

}

 Java Method References
Java provides a new feature called method reference in Java 8. Method reference is used to refer method of functional interface. It is compact and easy form of lambda expression. Each time when you are using lambda expression to just referring a method, we can replace our lambda expression with method reference.

Types of Method References
There are following types of method references in java:
1. Reference to a static method.
2. Reference to an instance method.
3. Reference to a constructor.

1) Reference to a Static Method
We can refer to static method defined in the class. Following is the syntax and example which describe the process of referring static method in Java.
Syntax:
ContainingClass::staticMethodName
Example:
In the following example, we have defined a functional interface and referring a static method to it’s functional method add().
import java.util.function.BiFunction;

class Arithmetic
{
public static int add(int a, int b)
{
return a+b;
}
}
public class MethodReference
{
public static void main(String[] args)
{
BiFunction<Integer, Integer, Integer> adder = Arithmetic::add;
int result = adder.apply(10, 20);
System.out.println(result);
}
}
2) Reference to an Instance Method
like static methods, we can refer instance methods also. In the following example, we are describing the process of referring the instance method.
Syntax:
containingObject::instanceMethodName

Example:
import java.util.function.BiFunction;

class Arithmetic
{
public int add(int a, int b)
{
return a+b;
}
}
public class InstanceMethodReference
{
public static void main(String[] args)
{
BiFunction<Integer, Integer, Integer>adder = new Arithmetic()::add;
int result = adder.apply(10, 20);
System.out.println(result);
}
}

3) Reference to a Constructor
We can refer a constructor by using the new keyword. Here, we are referring constructor with the help of functional interface.
Syntax:
ClassName::new

Example:
interface Messageable
{
Message getMessage(String msg);
}
class Message
{
Message(String msg)
{
System.out.print(msg);
}

}
public class Demo
{
public static void main(String[] args)
{
Messageable hello = Message::new;
hello.getMessage(“Hello”);
}
}

 Java Stream API
Java provides a new additional package in Java 8 called java.util.stream. This package consists of classes, interfaces and enum to allows functional-style operations on the elements. We can use stream by importing java.util.stream package.
By using streams we can perform various aggregate operations on the data returned from collections, arrays, Input/Output operations.
Stream provides following features:
• Stream does not store elements. It simply conveys elements from a source such as a data structure, an array, or an I/O channel, through a pipeline of computational operations.
• Stream is functional in nature. Operations performed on a stream does not modify it’s source. For example, filtering a Stream obtained from a collection produces a new Stream without the filtered elements, rather than removing elements from the source collection.
• 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.

Java Stream Example
To understand how stream works, lets take an example without using stream and then we will see the same example with streams.
Finding certain strings without using Stream
import java.util.ArrayList;
import java.util.List;
public class Example{
public static void main(String[] args) {
List names = new ArrayList();
names.add(“Ajeet”);
names.add(“Negan”);
names.add(“Aditya”);
names.add(“Steve”);
int count = 0;
for (String str : names) {
if (str.length() < 6)
count++;
}
System.out.println(“There are “+count+” strings with length less than 6″);
}
}

Output:
There are 3 strings with length less than 6

Same example using Stream
import java.util.ArrayList;
import java.util.List;
public class Example
{
public static void main(String[] args)
{
List names = new ArrayList();
names.add(“Ajeet”);
names.add(“Negan”);
names.add(“Aditya”);
names.add(“Steve”);

//Using Stream and Lambda expression
long count = names.stream().filter(str->str.length()<6).count();
System.out.println(“There are “+count+” strings with length less than 6″);

}
}
Output:
There are 3 strings with length less than 6

How to work with Stream in Java
As we have seen in the above example, the working of stream can be explained in three stages:
1. Create a stream
2. Perform intermediate operations on the initial stream to transform it into another stream and so on on further intermediate operations. In the above example, the filter() operation is intermediate operation, there can be more than one intermediate operations.
3. Perform terminal operation on the final stream to get the result. In the above example, the count() operation is terminal operation.

Examples of Intermediate operartions
Intermediate operations return the stream itself
1. Stream.filter()
Filter accepts a predicate to filter all elements of the stream. This operation is intermediate which enables us to call another stream operation (e.g. forEach) on the result.
public class Demo
{
public static void main(String[] args)
{
List memberNames = new ArrayList<>();
memberNames.add(“Amitabh”);
memberNames.add(“Shekhar”);
memberNames.add(“Aman”);
memberNames.add(“Rahul”);
memberNames.add(“Shahrukh”);
memberNames.add(“Salman”);
memberNames.add(“Yana”);
memberNames.add(“Lokesh”);

memberNames.stream().filter((s) -> s.startsWith(“A”))
.forEach(System.out::println);
}
}
Output:-
Amitabh
Aman

2. Stream.map()
The intermediate operation map converts each element into another object via the given function. The following example converts each string into an upper-cased string. But you can also use map to transform each object into another type.
For above same list
memberNames.stream().filter((s) -> s.startsWith(“A”))
.map(String::toUpperCase)
.forEach(System.out::println);

Output:
AMITABH
AMAN

3. Stream.sorted()
Sorted is an intermediate operation which returns a sorted view of the stream. The elements are sorted in natural order unless you pass a custom Comparator.
memberNames.stream().sorted()
.map(String::toUpperCase)
.forEach(System.out::println);
Output:

AMAN
AMITABH
LOKESH
RAHUL
SALMAN
SHAHRUKH
SHEKHAR
YANA

Terminal Operartions:
Terminal operations return a result of a certain type instead of again a Stream.

4. Stream.forEach()
This method helps in iterating over all elements of a stream and perform some operation on each of them. The operation is passed as lambda expression parameter.
memberNames.forEach(System.out::println);

5. Stream.collect()
collect() method used to recieve elements from a sream and store them in a collection and metioned in parameter funcion.
List memNamesInUppercase = memberNames.stream().sorted()
.map(String::toUpperCase)
.collect(Collectors.toList());

System.out.print(memNamesInUppercase);

Outpout: [AMAN, AMITABH, LOKESH, RAHUL, SALMAN, SHAHRUKH, SHEKHAR, YANA]
6. Stream.count()
Count is a terminal operation returning the number of elements in the stream as a long.
long totalMatched = memberNames.stream()
.filter((s) -> s.startsWith(“A”))
.count();

System.out.println(totalMatched);

Output: 2

 Java Default Methods
Java provides a facility to create default methods inside the interface. Methods which are defined inside the interface and tagged with default are known as default methods. These methods are non-abstract methods.
Default method Example:
In the following example, Sayable is a functional interface that contains a default and an abstract method. The concept of default method is used to define a method with default implementation. We can override default method also to provide more specific implementation for the method.

Example:-

interface Sayable
{
// Default method
default void say()
{
System.out.println(“Hello, this is default method”);
}

}
public class DefaultMethods implements Sayable{

public static void main(String[] args)
{
DefaultMethods dm = new DefaultMethods();

dm.say(); // calling default method

}
}

 Static Methods Interface
We can also define static methods inside the interface. Static methods are used to define utility methods. The following example explain, how to implement static method in interface.
interface Printable
{
static void print(String msg)
{
System.out.println(msg);
}
}
public class DefaultMethods implements Printable
{

public static void main(String[] args)
{
DefaultMethods dm = new DefaultMethods();

Printable.print(“Helloooo…”); // calling static method
}
}

 Java 8 – New Date/Time API

With Java 8, a new Date-Time API is introduced to cover the following drawbacks of old date-time API.
• Not thread safe − java.util.Date is not thread safe, thus developers have to deal with concurrency issue while using date. The new date-time API is immutable and does not have setter methods.
• Poor design − Default Date starts from 1900, month starts from 1, and day starts from 0, so no uniformity. The old API had less direct methods for date operations. The new API provides numerous utility methods for such operations.
• Difficult time zone handling − Developers had to write a lot of code to deal with timezone issues. The new API has been developed keeping domain-specific design in mind.
Java 8 introduces a new date-time API under the package java.time. Following are some of the important classes introduced in java.time package.
• Local − Simplified date-time API with no complexity of timezone handling.
• Zoned − Specialized date-time API to deal with various timezones.

1. Local Date-Time API
LocalDate/LocalTime and LocalDateTime classes simplify the development where timezones are not required.

The new classes intended to replace Date class are LocalDate, LocalTime and LocalDateTime
LocalDate
The LocalDate class represents a date. There is no representation of a time or time-zone.
LocalDate localDate = LocalDate.now();
System.out.println(localDate.toString()); //2013-05-15
System.out.println(localDate.getDayOfWeek().toString()); //WEDNESDAY
System.out.println(localDate.getDayOfMonth()); //15
System.out.println(localDate.getDayOfYear()); //135
System.out.println(localDate.isLeapYear()); //false
System.out.println(localDate.plusDays(12).toString()); //2013-05-27

LocalTime
The LocalTime class represents a time. There is no representation of a date or time-zone.

LocalTime localTime = LocalTime.of(12, 20);
System.out.println(localTime.toString()); //12:20
System.out.println(localTime.getHour()); //12
System.out.println(localTime.getMinute()); //20
System.out.println(localTime.getSecond()); //0
System.out.println(localTime.MIDNIGHT); //00:00
System.out.println(localTime.NOON); //12:00

LocalDateTime
The LocalDateTime class represents a date-time. There is no representation of a time-zone.
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime.toString()); //2013-05-15T10:01:14.911
System.out.println(localDateTime.getDayOfMonth()); //15
System.out.println(localDateTime.getHour()); //10
System.out.println(localDateTime.getNano()); //911000000

2. Zoned Date-Time API
Zoned date-time API is to be used when time zone is to be considered.
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class DateExample
{
public static void main(String[] args)
{
DateExample dateExample = new DateExample ();
dateExample.testZonedDateTime();
}

public void testZonedDateTime() {

ZonedDateTime date1 = ZonedDateTime.parse(“2018-11-12T10:15:30+05:30[Asia/Karachi]”);
System.out.println(“date1: ” + date1);

ZoneId id = ZoneId.of(“Europe/Paris”);
System.out.println(“ZoneId: ” + id);

ZoneId currentZone = ZoneId.systemDefault();
System.out.println(“CurrentZone: ” + currentZone);
}
}
 Java forEach()
Java provides a new method forEach() to iterate the elements. It is defined in Iterable and Stream interface. It is a default method defined in the Iterable interface. Collection classes which extends Iterable interface can use forEach loop to iterate elements.
Example 1 – forEach to iterate a List
import java.util.ArrayList;
import java.util.List;
public class ForEachExample
{
public static void main(String[] args)
{
List gamesList = new ArrayList();
gamesList.add(“Football”);
gamesList.add(“Cricket”);
gamesList.add(“Chess”);
gamesList.add(“Hocky”);

gamesList.forEach(games -> System.out.println(games));

}
}

Example 2 – forEach to iterate a Stream
import java.util.List;
import java.util.ArrayList;

public class Example
{
public static void main(String[] args)
{
List names = new ArrayList();
names.add(“Maggie”);
names.add(“Michonne”);
names.add(“Rick”);
names.add(“Merle”);
names.add(“Governor”);
names.stream()
.filter(f->f.startsWith(“M”))
.forEach(System.out::println);
}
}

 Java Base64 Encode and Decode
Java provides a class Base64 to deal with encryption. We can encrypt and decrypt your data by using provided methods. We need to import java.util.Base64 in our source file to use its methods.
This class provides three different encoders and decoders to encrypt information at each level. We can use these methods at the following levels.
Basic Encoding and Decoding
It uses the Base64 alphabet specified by Java in RFC 4648 and RFC 2045 for encoding and decoding operations. The encoder does not add any line separator character. The decoder rejects data that contains characters outside the base64 alphabet.
1) Encoding String to base64:
import java.nio.charset.StandardCharsets;
import java.util.Base64;

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

Base64.Encoder encoder = Base64.getEncoder();
String normalString = “VilMinds”;
String encodedString = encoder.encodeToString(normalString.getBytes(StandardCharsets.UTF_8) );
System.out.println(encodedString);
}
}

2) Decoding a base64 encoded String :
import java.util.Base64;

public class Demo
{

public static void main(String[] args)
{
String encodedString = “VmlsTWluZHM=”;
Base64.Decoder decoder = Base64.getDecoder();
byte[] decodedByteArray = decoder.decode(encodedString);

System.out.println(new String(decodedByteArray));

}
}

Output : VilMinds
 Java Parallel Array Sorting
Java provides a new additional feature in Array class which is used to sort array elements parallel.New methods has added to java.util.Arrays package that use the JSR 166 Fork/Join parallelism common pool to provide sorting of arrays in parallel.The methods are called parallelSort() and are overloaded for all the primitive data types and Comparable objects.
Advantage of Parallel Sort Over Simple Sort:
The parallelSort() method uses the concept of multithreading which makes it much faster compared to the normal sort when there are lot of elements.

Example:-

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+” “);
}
}
}

Output:-
5 8 1 0 6 9
Array elements after sorting
0 1 5 6 8 9

 Nashorn JavaScript Engine
Nashorn is a JavaScript engine. It is used to execute JavaScript code dynamically at JVM (Java Virtual Machine). Java provides a command-line tool jjs which is used to execute JavaScript code.
You can execute JavaScript code by using jjs command-line tool and by embedding into Java source code.
Example: Executing by Using Terminal
Following is the step by step process to execute JavaScript code at the JVM.
1) Create a file hello.js.
2) Write and save the following code into the file.
var hello = function(){
print(“Hello Nashorn”);
};
hello();
3) Open terminal
4) Write command jjs hello.js and press enter.
After executing command, you will see the below output.
Output:
Hello Nashorn

Example: Executing JavaScript file in Java Code
You can execute JavaScript file directly from your Java file. In the following code, we are reading a file hello.js with the help of FileReader class.
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(“js/hello.js”));
}
}

 Java Optional Class
Java introduced a new class Optional in jdk8. It is a public final class and used to deal with NullPointerException in Java application. You must import java.util package to use this class. It provides methods which are used to check the presence of value for particular variable.
Example :-
import java.util.Optional;

public class Demo
{
public static void main(String[] args)
{
String[] str = new String[10];
Optional checkNull = Optional.ofNullable(str[5]);
if(checkNull.isPresent())
{
String lowercaseString = str[5].toLowerCase();
System.out.print(lowercaseString);
}
Else
{
System.out.println(“string value is not present”);
}

}
}

 Java StringJoiner
Java added a new final class StringJoiner in java.util package. It is used to construct a sequence of characters separated by a delimiter. Now, we can create string by passing delimiters like comma(,), hyphen(-) etc. You can also pass prefix and suffix to the char sequence.

import java.util.StringJoiner;

public class StringJoinerExample
{
public static void main(String[] args)
{
StringJoiner joinNames = new StringJoiner(“,”); // passing comma(,) as delimiter

// Adding values to StringJoiner
joinNames.add(“Rahul”);
joinNames.add(“Raju”);
joinNames.add(“Peter”);
joinNames.add(“Raheem”);

System.out.println(joinNames);
}
}

Output : Rahul,Raju,Peter,Raheem

 Java 8 JDBC Improvements
In Java 8, Java made two major changes in JDBC API.
1) The JDBC-ODBC Bridge has been removed.
Oracle does not support the JDBC-ODBC Bridge. Oracle recommends that you use JDBC drivers provided by the vendor of your database instead of the JDBC-ODBC Bridge.
2) Added some new features in JDBC 4.2.
Java JDBC 4.2 introduces the following features:
• Addition of REF_CURSOR support.
• Addition of java.sql.DriverAction Interface
• Addition of security check on deregisterDriver Method in DriverManager Class
• Addition of the java.sql.SQLType Interface
• Addition of the java.sql.JDBCType Enum
• Add Support for large update counts
• Changes to the existing interfaces
• Rowset 1.2: Lists the enhancements for JDBC RowSet.