modern programming in java 8 - lambdas, streams and date time api

Post on 15-Jan-2017

623 Views

Category:

Software

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Modern Programming in Java 8 Lambdas, Streams and Date/Time API

GANESH & HARI CODEOPS TECHNOLOGIES

ganesh@codeops.techhari@codeops.tech

Adapt: Learn functional programming

Agenda• Introduction & Overview

• Lambdas

• Functional interfaces

• Streams

• Parallel Streams

• Date & Time package

• Refactoring to Java 8

Java meets functional programming (with lambdas)

Java is not your grandma’s language anymore!

Greek characters are scary!

He he, but lambdas are fun, not scary

List<String> strings = Arrays.asList("eeny", "meeny", "miny", "mo");Consumer<String> printString = string -> System.out.println(string); strings.forEach(printString);

Lambda functions!

But what are lambdas?

Lambdas is just a fancy name for functions

without a name!

What are lambda functions?

❖ (Java 8) One way to think about lambdas is “anonymous function” or “unnamed function” - they are functions without a name and are not associated with any class

❖ They don’t change external state

What is functional programming?

❖ Functional languages view programs as an entity—called a function—that accepts inputs and produces output

❖ Functions are connected together by their outputs to other functions’ inputs

❖ Underlying approach: “Evaluate an expression. Then use the results for something else.”

Perspective - for loops!List<String> strings = Arrays.asList("eeny", "meeny", "miny", "mo");for(String string : strings) {

System.out.println(string);}

External Iteration

Perspective - for loops!

List<String> strings = Arrays.asList("eeny", "meeny", "miny", "mo");strings.forEach(string -> System.out.println(string));

Internal Iteration

Perspective - for loops!

List<String> strings = Arrays.asList("eeny", "meeny", "miny", "mo");strings.forEach(string -> System.out.println(string));

Internal Iteration

List<String> strings = Arrays.asList("eeny", "meeny", "miny", "mo");for(String string : strings) {

System.out.println(string);}

External Iteration

Perspective - for loops!

List<String> strings = Arrays.asList("eeny", "meeny", "miny", "mo");strings.forEach(string -> System.out.println(string));

Internal Iteration

List<String> strings = Arrays.asList("eeny", "meeny", "miny", "mo");for(String string : strings) {

System.out.println(string);}

External Iteration

Procedural thinking

Functional thinking

You can use lambdas for some amazing stuff

sediment

pre-carbon

ultra-filter

post-carbon

Filtered water

E.g., you can compose lambda functions as in pipes-and-filters

$ cat limerick.txt There was a young lady of Niger Who smiled as she rode on a tiger. They returned from the ride With the lady inside And a smile on the face of the tiger.

$ cat limerick.txt | tr -cs "[:alpha:]" "\n" | awk '{print length(), $0}' | sort | uniq

1 a 2 as 2 of 2 on 3 And 3 Who 3 she 3 the 3 was 4 They 4 With 4 face 4 from 4 lady 4 ride 4 rode 5 Niger 5 There 5 smile 5 tiger 5 young 6 inside 6 smiled 8 returned

List<String> lines = Files.readAllLines(Paths.get("./limerick.txt"), Charset.defaultCharset());

Map<Integer, List<String>> wordGroups = lines.stream() .map(line -> line.replaceAll("\\W", "\n").split("\n")) .flatMap(Arrays::stream) .sorted() .distinct() .collect(Collectors.groupingBy(String::length));

wordGroups.forEach( (count, words) -> { words.forEach(word -> System.out.printf("%d %s %n", count, word)); });

1 a 2 as 2 of 2 on 3 And 3 Who 3 she 3 the 3 was 4 They 4 With 4 face 4 from 4 lady 4 ride 4 rode 5 Niger 5 There 5 smile 5 tiger 5 young 6 inside 6 smiled 8 returned

Lambdas & streams help in productive programming!

public static void main(String []file) throws Exception { // process each file passed as argument

// try opening the file with FileReader try (FileReader inputFile = new FileReader(file[0])) { int ch = 0; while( (ch = inputFile.read()) != -1) { // ch is of type int - convert it back to char System.out.print( (char)ch ); } } // try-with-resources will automatically release FileReader object }

public static void main(String []file) throws Exception { Files.lines(Paths.get(file[0])).forEach(System.out::println); }

Existing APIs are enriched with lambdas and streams support

Java 8 is the new Groovy ;-)importjava.io.*;

classType{ publicsta7cvoidmain(String[]files){ //processeachfilepassedasargument for(Stringfile:files){ //tryopeningthefilewithFileReader try(FileReaderinputFile=newFileReader(file)){ intch=0; while((ch=inputFile.read())!=-1){ //chisoftypeint-convertitbacktochar System.out.print((char)ch); } }catch(FileNotFoundExcep7onfnfe){ System.err.prinR("Cannotopenthegivenfile%s",file); } catch(IOExcep7onioe){ System.err.prinR("Errorwhenprocessingfile%s;skippingit",file); } //try-with-resourceswillautoma7callyreleaseFileReaderobject } }}

args.each{printlnnewFile(it).getText()}

Agenda• Introduction & Overview

• Lambdas

• Functional interfaces

• Streams

• Parallel streams

• Date & Time package

• Refactoring to Java 8

Java 8 lambdas - “Hello world!”

interface LambdaFunction { void call(); }

class FirstLambda { public static void main(String []args) { LambdaFunction lambdaFunction = () -> System.out.println("Hello world"); lambdaFunction.call(); } }

Java 8 lambdas - “Hello world!”

interface LambdaFunction { void call(); }

class FirstLambda { public static void main(String []args) { LambdaFunction lambdaFunction = () -> System.out.println("Hello world"); lambdaFunction.call(); } }

Functional interface - provides signature for lambda functions

Lambda function/expression

Call to the lambda

Prints “Hello world” on the console when executed

Parts of a lambda expression

() -> System.out.println("Hello world");

No parameters, i.e., ()

Arrow operator that separates parameters and the body The lambda body

Return type “void” inferred from the body

Method references

Method references - “syntactic sugar” for lambda functions

They “route” function parameters

arg -> System.out.println(arg)

System.out::println

Method references

List<String> strings = Arrays.asList("eeny", "meeny", "miny", "mo"); Consumer<String> printString = System.out::println; strings.forEach(printString);

Method reference

List<String> strings = Arrays.asList("eeny", "meeny", "miny", "mo"); Consumer<String> printString = string -> System.out.println(string); strings.forEach(printString);

Method references

Cannot use method references when lambda functions do more than“routing” function parameters

strings.forEach(string -> System.out.println(string.toUpperCase()));

More processing here than just “routing” parameters

Method references List<String> strings = Arrays.asList("eeny", "meeny", "miny", "mo"); Consumer<String> printString = System.out::println; strings.forEach(printString);

public static void printUpperCaseString(String string) { System.out.println(string.toUpperCase()); }

strings.forEach(MethodReference::printUpperCaseString);

“Effectively final” variables

import java.util.Arrays; import java.util.List;

class PigLatin { public static void main(String []args) { String suffix = "ay"; List<String> strings = Arrays.asList("one", "two", "three", "four"); strings.forEach(string -> System.out.println(string + suffix)); } } Accessing “local variable” suffix

here; hence it is considered “effectively final”

“Effectively final” variablesimport java.util.Arrays; import java.util.List;

class PigLatin { public static void main(String []args) { String suffix = "ay"; List<String> strings = Arrays.asList("one", "two", "three", “four");

suffix = "e"; // assign to suffix variable strings.forEach(string -> System.out.println(string + suffix)); } }

PigLatinAssign.java:9: error: local variables referenced from a lambda expression must be final or effectively final strings.forEach(string -> System.out.println(string + suffix)); ^ 1 error

Agenda• Introduction & Overview

• Lambdas

• Functional interfaces

• Streams

• Parallel streams

• Date & Time package

• Refactoring to Java 8

Functional interfaces

@FunctionalInterface interface LambdaFunction { void call(); }

Functional interface

Abstract method providing the signature of the lambda function

Annotation to explicitly state that it is a functional interface

Java 8 lambdas - “Hello world!”

@FunctionalInterface interface LambdaFunction { void call(); }

class FirstLambda { public static void main(String []args) { LambdaFunction lambdaFunction = () -> System.out.println("Hello world"); lambdaFunction.call(); } }

Functional interface - provides signature for lambda functions

Lambda function/expression

Call to the lambda

Prints “Hello world” on the console when executed

Older Single Abstract Methods (SAMs)

// in java.lang package interface Runnable { void run(); }

// in java.util package interface Comparator<T> { boolean compare(T x, T y); }

// java.awt.event package: interface ActionListener { void actionPerformed(ActionEvent e) }

// java.io package interface FileFilter { boolean accept(File pathName); }

Functional interfaces: Single abstract methods

@FunctionalInterface interface LambdaFunction { void call();

// Single Abstract Method (SAM) }

Using built-in functional interfaces// within Iterable interface default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t);

} }

// in java.util.function package @FunctionalInterface public interface Consumer<T> {

void accept(T t); // the default andThen method elided

}

Using built-in functional interfaces

List<String> strings = Arrays.asList("eeny", "meeny", "miny", "mo"); Consumer<String> printString = string -> System.out.println(string); strings.forEach(printString);

List<String> strings = Arrays.asList("eeny", "meeny", "miny", "mo"); strings.forEach(string -> System.out.println(string));

Default methods in interfacespublic interface Iterator<E> {

boolean hasNext();

E next();

default void remove() { throw new UnsupportedOperationException("remove");

}

default void forEachRemaining(Consumer<? super E> action) { Objects.requireNonNull(action);

while (hasNext()) action.accept(next());

} }

“Diamond” inheritance problem?

“Diamond” inheritance problem?

interface Interface1 { default public void foo() { System.out.println("Interface1’s foo"); } }

interface Interface2 { default public void foo() { System.out.println("Interface2’s foo"); } }

public class Diamond implements Interface1, Interface2 { public static void main(String []args) { new Diamond().foo(); } }

Error:(9, 8) java: class Diamond inherits unrelated defaults for foo() from types Interface1 and Interface2

“Diamond” inheritance problem?

interface Interface1 { default public void foo() { System.out.println("Interface1’s foo"); } }

interface Interface2 { default public void foo() { System.out.println("Interface2’s foo"); } }

public class Diamond implements Interface1, Interface2 { public void foo() { Interface1.super.foo(); }

public static void main(String []args) { new Diamond().foo(); } }

Add this definition to resolve the

ambiguity

“Diamond” inheritance problem?

class BaseClass { public void foo() { System.out.println("BaseClass’s foo"); } }

interface BaseInterface { default public void foo() { System.out.println("BaseInterface’s foo”); } }

public class Diamond extends BaseClass implements BaseInterface { public static void main(String []args) { new Diamond().foo(); } }

Compiles cleanly; Java 8 rules help deal with the

diamond problem

Built-in functional interfaces

Built-in functional interfaces are a part of the java.util.function

package (in Java 8)

Built-in interfacesPredicate<T> Checks a condition and returns a

boolean value as resultIn filter() method in java.util.stream.Stream which is used to remove elements in the stream that don’t match the given condition (i.e., predicate) as Consumer<T> Operation that takes an argument but

returns nothingIn forEach() method in collections and in java.util.stream.Stream; this method is used for traversing all the elements in the collection or Function<T,

R>Functions that take an argument and return a result

In map() method in java.util.stream.Stream to transform or operate on the passed value and return a result.

Supplier<T> Operation that returns a value to the caller (the returned value could be same or different values)

In generate() method in java.util.stream.Stream to create a infinite stream of elements.

Predicate interface

Stream.of("hello", "world") .filter(str -> str.startsWith("h")) .forEach(System.out::println);

The filter() method takes a Predicate as an argument (predicates are

functions that check a condition and return a boolean value)

Predicate interface

Predicate interface

A Predicate<T> “affirms” something as true or false: it takes an argument of type T, and returns a

boolean value. You can call test() method on a Predicate object.

@FunctionalInterface public interface Predicate<T> {

boolean test(T t); // other methods elided

}

Predicate interface: Example

import java.util.function.Predicate;

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

Predicate<String> nullCheck = arg -> arg != null; Predicate<String> emptyCheck = arg -> arg.length() > 0; Predicate<String> nullAndEmptyCheck = nullCheck.and(emptyCheck); String helloStr = "hello"; System.out.println(nullAndEmptyCheck.test(helloStr)); String nullStr = null; System.out.println(nullAndEmptyCheck.test(nullStr));

} }

Prints: truefalse

Predicate interface: Example

import java.util.List; import java.util.ArrayList;

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

List<String> greeting = new ArrayList<>(); greeting.add("hello"); greeting.add("world"); greeting.removeIf(str -> !str.startsWith("h")); greeting.forEach(System.out::println);

} }

Prints: hello

Consumer interface

Stream.of("hello", "world") .forEach(System.out::println);

// void forEach(Consumer<? super T> action);

Prints: helloworld

Consumer interface

Consumer interface

A Consumer<T> “consumes” something: it takes an argument (of generic type T) and returns

nothing (void). You can call accept() method on a Consumer object.

@FunctionalInterface public interface Consumer<T> {

void accept(T t); // the default andThen method elided

}

Consumer interface: Example

Consumer<String> printUpperCase = str -> System.out.println(str.toUpperCase());

printUpperCase.accept("hello");

Prints: HELLO

Consumer interface: Example

import java.util.stream.Stream; import java.util.function.Consumer;

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

Stream<String> strings = Stream.of("hello", "world"); Consumer<String> printString = System.out::println; strings.forEach(printString);

} }

Prints: helloworld

Function interface

import java.util.Arrays;

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

Arrays.stream("4, -9, 16".split(", ")) .map(Integer::parseInt) .map(i -> (i < 0) ? -i : i) .forEach(System.out::println);

} }

Prints: 4916

Function interface

Function interface

A Function<T, R> “operates” on something and returns something: it takes one argument (of

generic type T) and returns an object (of generic type R). You can call apply() method on a Function

object.

@FunctionalInterface public interface Function<T, R> {

R apply(T t); // other methods elided

}

Function interface: Example

Function<String, Integer> strLength = str -> str.length(); System.out.println(strLength.apply("supercalifragilisticexpialidocious"));

Prints: 34

Function interface: Example

import java.util.Arrays; import java.util.function.Function;

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

Function<String, Integer> parseInt = Integer:: parseInt ; Function<Integer, Integer> absInt = Math:: abs ; Function<String, Integer> parseAndAbsInt = parseInt.andThen(absInt); Arrays.stream("4, -9, 16".split(", "))

.map(parseAndAbsInt)

.forEach(System. out ::println); }

}

Prints: 4916

Supplier interface

import java.util.stream.Stream; import java.util.Random;

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

Random random = new Random(); Stream.generate(random::nextBoolean)

.limit(2)

.forEach(System.out::println); }

}

Prints two boolean values “true” and “false”

in random order

Supplier interface

Supplier interface

A Supplier<T> “supplies” takes nothing but returns something: it has no arguments and

returns an object (of generic type T). You can call get() method on a Supplier object

@FunctionalInterface public interface Supplier<T> {

T get(); // no other methods in this interface

}

Supplier interface: Example

Supplier<String> currentDateTime = () -> LocalDateTime.now().toString(); System.out.println(currentDateTime.get());

Prints current time: 2015-10-16T12:40:55.164

Summary of built-in interfaces in java.util.function interface

❖ There are only four core functional interfaces in this package: Predicate, Consumer, Function, and Supplier.

❖ The rest of the interfaces are primitive versions, binary versions, and derived interfaces such as UnaryOperator interface.

❖ These interfaces differ mainly on the signature of the abstract methods they declare.

❖ You need to choose the suitable functional interface based on the context and your need.

Agenda• Introduction & Overview

• Lambdas

• Functional interfaces

• Streams

• Parallel streams

• Date & Time package

• Refactoring to Java 8

Java 8 streams (and parallel streams):Excellent example of applying functional

programming in practice

But what are streams?

Arrays.stream(Object.class.getMethods()) .map(method -> method.getName()) .distinct() .forEach(System.out::println);

wait equals toString hashCode getClass notify notifyAll

Method[] objectMethods = Object.class.getMethods(); Stream<Method> objectMethodStream = Arrays.stream(objectMethods); Stream<String> objectMethodNames

= objectMethodStream.map(method -> method.getName()); Stream<String> uniqueObjectMethodNames = objectMethodNames.distinct(); uniqueObjectMethodNames.forEach(System.out::println);

Arrays.stream(Object.class.getMethods()) .map(method -> method.getName()) .distinct() .forEach(System.out::println);

Breaking up into separate (looong)

stream pipelineStreamsource

Intermediateopera1ons

Terminalopera1on

stream

stream

Examples:IntStream.range(),Arrays.stream()

Examples:map(),filter(),dis1nct(),sorted()

Examples:sum(),collect(),forEach(),reduce()

DoubleStream.of(1.0,4.0,9.0) map(Math::sqrt) .peek(System.out::

println)

StreamSource(withelements1.0,4.0,and9.0)

IntermediateOpera=on1(mapsto

elementvalues1.0,2.0,and3.0)

IntermediateOpera=on2

(prints1.0,2.0,and3.0)

.sum();

TerminalOpera=on(returnsthesum6.0)

DoubleStream.of(1.0, 4.0, 9.0) .map(Math::sqrt) .peek(System.out::println) .sum();

IntStream.range(1, 6)

You can use range or iterate factory methods in the

IntStream interface

IntStream.iterate(1, i -> i + 1).limit(5)

1 2 3 4 5

1 4 9 16 25

map(i->i*i)

IntStream.range(1, 5).map(i -> i * i).forEach(System.out::println);

Using streams instead of imperative for i = 1 to 5, print i * i

Stream.of (1, 2, 3, 4, 5) .map(i -> i * i) .peek(i -> System.out.printf("%d ", i)) .count();

prints: 1 4 9 16 25

stream can be infinite

IntStream.iterate(0, i -> i + 2).forEach(System.out::println);

This code creates infinite stream of even numbers!

IntStream .iterate(0, i -> i + 2) .limit(5) .forEach(System.out::println);

Using the “limit” function to limit the stream to 5 integers

IntStream chars = "bookkeep".chars(); System.out.println(chars.count()); chars.distinct().sorted().forEach(ch -> System.out.printf("%c ", ch));

Cannot “reuse” a stream; this code throws IllegalStateException

Streams are lazy!

Files.lines(Paths.get("FileRead.java")).forEach(System.out::println);

This code prints the contents of the file “FileRead.java” in the

current directory

Pattern.compile(" ").splitAsStream("java 8 streams").forEach(System.out::println);

This code splits the input string “java 8 streams” based on whitespace and hence

prints the strings “java”, “8”, and “streams” on the console

new Random().ints().limit(5).forEach(System.out::println);

Generates 5 random integers and prints them on the console

"hello".chars().sorted().forEach(ch -> System.out.printf("%c ", ch));

Extracts characters in the string “hello”, sorts the chars and prints the chars

Agenda• Introduction & Overview

• Lambdas

• Functional interfaces

• Streams

• Parallel streams

• Date & Time package

• Refactoring to Java 8

Parallel Streams

race conditions

deadlocks

I really really hate concurrency problems

Parallel code

Serial code

Sometimes, dreams do come true even at 86 :-)

So, keep dreaming till you become 86!

long numOfPrimes = LongStream.rangeClosed(2, 100_000) .filter(PrimeNumbers::isPrime) .count();

System.out.println(numOfPrimes);

Prints 9592

2.510 seconds

Parallel code

Serial code

Let’s flip the switch by calling parallel() function

long numOfPrimes = LongStream.rangeClosed(2, 100_000) .parallel() .filter(PrimeNumbers::isPrime) .count();

System.out.println(numOfPrimes);

Prints 9592

1.235 seconds

Wow! That’s an awesome flip switch!

Internally, parallel streams make use of fork-join framework

import java.util.Arrays;

class StringConcatenator { public static String result = ""; public static void concatStr(String str) { result = result + " " + str; } }

class StringSplitAndConcatenate { public static void main(String []args) { String words[] = "the quick brown fox jumps over the lazy dog".split(" "); Arrays.stream(words).forEach(StringConcatenator::concatStr); System.out.println(StringConcatenator.result); } }

Gives wrong results with with parallel() call

Agenda• Introduction & Overview

• Lambdas

• Functional interfaces

• Streams

• Parallel streams

• Date & Time package

• Refactoring to Java 8

–Craig Larman

"The critical design tool for software development is a mind well educated in design principles"

Design Smells: Example

Discussion Example

// using java.util.Date Date today = new Date(); System.out.println(today);

$ java DateUse Wed Dec 02 17:17:08 IST 2015

Why should we get the time and timezone details if I only want a date? Can

I get rid of these parts? No!

So What?!Date today = new Date(); System.out.println(today); Date todayAgain = new Date(); System.out.println(todayAgain);

System.out.println(today.compareTo(todayAgain) == 0);

Thu Mar 17 13:21:55 IST 2016 Thu Mar 17 13:21:55 IST 2016 false

What is going on here?

Joda API

JSR 310: Java Date and Time API

Stephen Colebourne

Refactoring for Date

Replace inheritance with delegation

java.time package!

Date, Calendar, and TimeZone Java 8 replaces these types

Refactored SolutionLocalDate today = LocalDate.now(); System.out.println(today); LocalDate todayAgain = LocalDate.now(); System.out.println(todayAgain); System.out.println(today.compareTo(todayAgain) == 0);

2016-03-17 2016-03-17 true

Works fine now!

Refactored Example … You can use only date, time, or even timezone, and combine them as

needed!

LocalDate today = LocalDate.now(); System.out.println(today); LocalTime now = LocalTime.now(); System.out.println(now);

ZoneId id = ZoneId.of("Asia/Tokyo"); System.out.println(id);

LocalDateTime todayAndNow = LocalDateTime.now(); System.out.println(todayAndNow);

ZonedDateTime todayAndNowInTokyo = ZonedDateTime.now(ZoneId.of("Asia/Tokyo")); System.out.println(todayAndNowInTokyo);

2016-03-17 13:28:06.927 Asia/Tokyo 2016-03-17T13:28:06.928 2016-03-17T16:58:06.929+09:00[Asia/Tokyo]

“Fluent interfaces”

❖ Code is more readable and easier to use:

❖ Classes in this package have numerous static methods (many of them factory methods)

❖ Methods in the classes follow a common naming convention (for example, they use the prefixes plus and minus to add or subtract date or time values)

java.time Sub-packages

❖ java.time.temporal —Accesses date/time fields and units

❖ java.time.format —Formats the input and output of date/time objects

❖ java.time.zone —Handles time zones

❖ java.time.chrono —Supports calendar systems such as Japanese and Thai calendars

ISO-8601 Calendar System Format

❖ The Java 8 date and time API uses ISO 8601 as the default calendar format.

❖ In this internationally accepted format, the date and time values are sorted from the largest to the smallest unit of time: year, month/week, day, hour, minute, second, and millisecond/nanosecond.

❖ Example: LocalDate is represented in the in a year-month-day format (YYYY-MM-DD), as in, 2015-10-26.

java.time.LocalDate

LocalDate newYear2016 = LocalDate.of(2016, 1, 1); System.out.println("New year 2016: " + newYear2016);

New year 2016: 2016-01-01

java.time.LocalDate

LocalDate valentinesDay = LocalDate.of(2016, 14, 2); System.out.println("Valentine's day is on: " + valentinesDay);

Exception in thread "main" java.time.DateTimeException: Invalid value

for MonthOfYear(valid values 1 - 12): 14

java.time.LocalDate

long visaValidityDays = 180L; LocalDate currDate = LocalDate.now(); System.out.println("My Visa expires on: " + currDate.plusDays(visaValidityDays));

My Visa expires on: 2016-04-23

Important Methods in LocalDate

java.time.LocalTime

LocalTime currTime = LocalTime.now(); System.out.println("Current time is: " + currTime);

Current time is: 12:23:05.072

java.time.LocalTime

System.out.println(LocalTime.of(18,30));

prints: 18:30

java.time.LocalTime

long hours = 6; long minutes = 30; LocalTime currTime = LocalTime.now(); System.out.println("Current time is: " + currTime); System.out.println("My meeting is at: " + currTime.plusHours(hours).plusMinutes(minutes));

Current time is: 12:29:13.624My meeting is at: 18:59:13.624

Important Methods in LocalTime

java.time.LocalDateTime

LocalDateTime currDateTime = LocalDateTime.now(); System.out.println("Today's date and current time is: " + currDateTime);

Today's date and current time is: 2015-10-29T21:04:36.376

java.time.LocalDateTime

LocalDateTime christmas = LocalDateTime.of(2015, 12, 25, 0, 0); LocalDateTime newYear = LocalDateTime.of(2016, 1, 1, 0, 0); System.out.println("New Year 2016 comes after Christmas 2015”

+ newYear.isAfter(christmas));

New Year 2016 comes after Christmas 2015? true

java.time.LocalDateTime

LocalDateTime dateTime = LocalDateTime.now(); System.out.println("Today's date and current time: " + dateTime); System.out.println("The date component is: " + dateTime.toLocalDate()); System.out.println("The time component is: " + dateTime.toLocalTime());

Today's date and current time: 2015-11-04T13:19:10.497

The date component is: 2015-11-04The time component is: 13:19:10.497

java.time.Instant

import java.time.Instant;

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

// prints the current timestamp with UTC as time zone Instant currTimeStamp = Instant.now(); System.out.println("Instant timestamp is: "+ currTimeStamp); // prints the number of seconds as Unix timestamp from epoch time System.out.println("Number of seconds elapsed: " + currTimeStamp.getEpochSecond()); // prints the Unix timestamp in milliseconds System.out.println("Number of milliseconds elapsed: " + currTimeStamp.toEpochMilli());

} }

Instant timestamp is: 2015-11-02T03:16:04.502ZNumber of seconds elapsed: 1446434164

Number of milliseconds elapsed: 1446434164502

java.time.Period

LocalDate manufacturingDate = LocalDate.of(2016, Month.JANUARY, 1); LocalDate expiryDate = LocalDate.of(2018, Month.JULY, 18); Period expiry = Period.between(manufacturingDate, expiryDate); System.out.printf("Medicine will expire in: %d years, %d months, and %d days (%s)\n", expiry.getYears(), expiry.getMonths(), expiry.getDays(), expiry);

Medicine will expire in: 2 years, 6 months, and 17 days (P2Y6M17D)

Important Methods in Period

The Java 8 date and time API differentiates how humans and computers use date- and time-related information.

For example, the Instant class represents a Unix timestamp and internally uses long and int variables.

Instant values are not very readable or usable by humans because the class does not support methods

related to day, month, hours, and so on (in contrast, the Period class supports such methods).

java.time.Duration

LocalDateTime comingMidnight = LocalDateTime.of(LocalDate.now().plusDays(1), LocalTime.MIDNIGHT);

LocalDateTime now = LocalDateTime.now(); Duration between = Duration.between(now, comingMidnight); System.out.println(between);

PT7H13M42.003S

Important Methods in Duration

Summary of Instant, Period and Duration

TemporalUnit

import java.time.temporal.ChronoUnit;

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

System.out.println("ChronoUnit DateBased TimeBased Duration"); System.out.println("---------------------------------------"); for(ChronoUnit unit : ChronoUnit.values()) {

System.out.printf("%10s \t %b \t\t %b \t\t %s %n”, unit, unit.isDateBased(), unit.isTimeBased(), unit.getDuration());

} }

}

ZoneId

System.out.println("My zone id is: " + ZoneId.systemDefault());

My zone id is: Asia/Kolkata

ZoneId AsiaKolkataZoneId = ZoneId.of("Asia/Kolkata");

ZonedDateTime

LocalDate currentDate = LocalDate.now(); LocalTime currentTime = LocalTime.now(); ZoneId myZone = ZoneId.systemDefault(); ZonedDateTime zonedDateTime = ZonedDateTime.of(currentDate, currentTime, myZone); System.out.println(zonedDateTime);

2015-11-05T11:38:40.647+05:30[Asia/Kolkata]

ZonedDateTime

ZoneId myZone = ZoneId.of("Asia/Kolkata"); LocalDateTime dateTime = LocalDateTime.now(); ZonedDateTime zonedDateTime = dateTime.atZone(myZone); ZoneOffset zoneOffset = zonedDateTime.getOffset(); System.out.println(zoneOffset);

+05:30

ZonedDateTimeZoneId singaporeZone = ZoneId.of(“Asia/Singapore"); ZonedDateTime dateTimeInSingapore =

ZonedDateTime.of(LocalDateTime.of(2016, Month.JANUARY, 1, 6, 0), singaporeZone);

ZoneId aucklandZone = ZoneId.of("Pacific/Auckland"); ZonedDateTime sameDateTimeInAuckland =

dateTimeInSingapore.withZoneSameInstant(aucklandZone);

Duration timeDifference = Duration.between( dateTimeInSingapore.toLocalTime(),

sameDateTimeInAuckland.toLocalTime());

System.out.printf("Time difference between %s and %s zones is %d hours”, singaporeZone, aucklandZone, timeDifference.toHours());

Time difference between Asia/Singapore and Pacific/Auckland zones is 5 hours

Daylight Savings

ZoneId kolkataZone = ZoneId.of("Asia/Kolkata"); Duration kolkataDST = kolkataZone.getRules().getDaylightSavings(Instant.now()); System.out.printf("Kolkata zone DST is: %d hours %n", kolkataDST.toHours());

ZoneId aucklandZone = ZoneId.of("Pacific/Auckland"); Duration aucklandDST = aucklandZone.getRules().getDaylightSavings(Instant.now()); System.out.printf("Auckland zone DST is: %d hours", aucklandDST.toHours());

Kolkata zone DST is: 0 hoursAuckland zone DST is: 1 hours

DateTimeFormatter

Predefined formatters: • ISO_DATE (2015-11-05) • ISO_TIME (11:25:47.624) • RFC_1123_DATE_TIME (Thu, 5 Nov 2015 11:27:22 +0530) • ISO_ZONED_DATE_TIME (2015-11-05T11:30:33.49+05:30[Asia/Kolkata])

DateTimeFormatter

Wake up time: 06:00:00

LocalTime wakeupTime = LocalTime.of(6, 0, 0); System.out.println("Wake up time: " + DateTimeFormatter.ISO_TIME.format(wakeupTime));

01 Jan 2016

DateTimeFormatter customFormat = DateTimeFormatter.ofPattern("dd MMM yyyy"); System.out.println(customFormat.format(LocalDate.of(2016, Month.JANUARY, 01)));

Uppercase and lowercase letters can have similar or different meanings when used in format strings fordates and times. Read the Javadoc for these patterns

carefully before trying to use these letters. For example,in dd-MM-yy, MM refers to month; however, in dd-mm-

yy, mm refers to minutes !

Formatting Dates

• G (era: BC, AD) • y (year of era: 2015, 15) • Y (week-based year: 2015, 15) • M (month: 11, Nov, November) • w (week in year: 13) • W (week in month: 2) • E (day name in week: Sun, Sunday) • D (day of year: 256) • d (day of month: 13)

Custom Date Patternspublic class CustomDatePatterns {

public static void main(String []args) { // patterns from simple to complex ones String [] dateTimeFormats = {

"dd-MM-yyyy", /* d is day (in month), M is month, y is year */ "d '('E')' MMM, YYYY", /*E is name of the day (in week), Y is year*/ "w'th week of' YYYY", /* w is the week of the year */ "EEEE, dd'th' MMMM, YYYY" /*E is day name in the week */

};

LocalDateTime now = LocalDateTime.now(); for(String dateTimeFormat : dateTimeFormats) {

System.out.printf("Pattern \"%s\" is %s %n", dateTimeFormat, DateTimeFormatter.ofPattern(dateTimeFormat).format(now));

} }

} Pattern "dd-MM-yyyy" is 05-11-2015Pattern "d '('E')' MMM, YYYY" is 5 (Thu) Nov, 2015Pattern "w'th week of' YYYY" is 45th week of 2015Pattern "EEEE, dd'th' MMMM, YYYY" is Thursday, 05th November, 2015

Formatting Times

• a (marker for the text a.m./p.m. marker) • H (hour: value range 0–23) • k (hour: value range 1–24) • K (hour in a.m./p.m.: value range 0–11) • h (hour in a.m./p.m.: value range 1–12) • m (minute) • s (second) • S (fraction of a second) • z (time zone: general time-zone format)

Custom Time Patternsclass CustomTimePatterns {

public static void main(String []args) { // patterns from simple to complex ones String [] timeFormats = {

"h:mm", /* h is hour in am/pm (1-12), m is minute */ "hh 'o''clock'", /* '' is the escape sequence to print a single quote */ "H:mm a", /* H is hour in day (0-23), a is am/pm*/ "hh:mm:ss:SS", /* s is seconds, S is milliseconds */ "K:mm:ss a" /* K is hour in am/pm(0-11) */

};

LocalTime now = LocalTime.now(); for(String timeFormat : timeFormats) {

System.out.printf("Time in pattern \"%s\" is %s %n", timeFormat, DateTimeFormatter.ofPattern(timeFormat).format(now));

} }

} Time in pattern "h:mm" is 12:27Time in pattern "hh 'o''clock'" is 12 o'clockTime in pattern "H:mm a" is 12:27 PMTime in pattern "hh:mm:ss:SS" is 12:27:10:41Time in pattern "K:mm:ss a" is 0:27:10 PM

Flight Travel - Time Calculation - Example

DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd MMM yyyy hh.mm a");

// Leaving on 1st Jan 2016, 6:00am from "Singapore" ZonedDateTime departure = ZonedDateTime.of(

LocalDateTime.of(2016, Month.JANUARY, 1, 6, 0), ZoneId.of("Asia/Singapore"));

System.out.println("Departure: " + dateTimeFormatter.format(departure));

// Arrival on the same day in 10 hours in "Auckland" ZonedDateTime arrival =

departure.withZoneSameInstant(ZoneId.of("Pacific/Auckland")).plusHours(10); System.out.println("Arrival: " + dateTimeFormatter.format(arrival));

Departure: 01 Jan 2016 06.00 AMArrival: 01 Jan 2016 09.00 PM

Agenda• Introduction & Overview

• Lambdas

• Functional interfaces

• Streams

• Parallel streams

• Date & Time package

• Refactoring to Java 8

Examples of refactorings (to Java 8)

❖ Convert anonymous inner classes to lambda expressions (when they are functional interfaces)

❖ Convert for/foreach loops to streams (i.e., external iteration to internal iteration)

Refactoring loops to streams

❖ Replace if conditions with ‘filter’ and calls to methods that return a boolean value (Predicate)

❖ Replace accumulation operations with reduce (or its special forms like sum, count, etc).

Source: LAMBDAFICATOR: From Imperative to Functional Programming through Automated Refactoring. Lyle Franklin; Alex Gyori; Jan Lahoda; Danny Dig. 35th International Conference on Software Engineering (ICSE), 2013.

Tool support for refactoring

❖ Most Java IDEs provide suggestions to automatically refactor to lambdas and streams

❖ IDEs that support Java 8 refactoring include: Eclipse, IntelliJ Idea and NetBeans

Refactoring suggestions in NetbeansImage source: http://refactoring.info/tools/LambdaFicator/

Java 8 Migration Aids in IntelliJ IDEAImage source: https://www.jetbrains.com/help/img/idea/ij_java_8_inspection_results_migration_runnable.png

Java 8 Refactorings in IntelliJ IDEAImage source: https://www.jetbrains.com/help/img/idea/ij_java_8_replace_method_reference_with_lambda.png

https://www.jetbrains.com/help/img/idea/ij_java_8_can_be_replaced_with_method_ref.png

Refactoring suggestions in NetbeansImage source: http://refactoring.info/tools/LambdaFicator/

Refactoring suggestions in NetbeansImage source: http://refactoring.info/tools/LambdaFicator/

Suggested Reading

❖ Refactoring with Loops and Collection Pipelines (Martin Fowler, 2015)

❖ Pragmatic Functional Refactoring with Java 8 (Raoul-Gabriel Urma & Richard Warburton, 2015)

❖ Migrating to Java 8 (IntelliJ IDEA, 2016)

Meetups

hYp://www.meetup.com/JavaScript-Meetup-Bangalore/hYp://www.meetup.com/Container-Developers-Meetup-Bangalore/hYp://www.meetup.com/So^ware-Cra^smanship-Bangalore-Meetup/hYp://www.meetup.com/Core-Java-Meetup-Bangalore/hYp://www.meetup.com/Technical-Writers-Meetup-Bangalore/hYp://www.meetup.com/CloudOps-Meetup-Bangalore/hYp://www.meetup.com/Bangalore-SDN-IoT-NetworkVirtualiza7on-Enthusiasts/hYp://www.meetup.com/So^wareArchitectsBangalore/

Image credits❖ http://mayhemandmuse.com/wp-content/uploads/2013/04/This-optical-illusion-drawing-by-WE-

Hill-shows-both-his-wife-and-his-mother-in-law.jpg

❖ http://www.webtrafficroi.com/wp-content/uploads/2012/10/mahatma-gandhi-apple-think-different.jpg

❖ http://rexx-language-association-forum.44760.x6.nabble.com/file/n2236/Ruby-lambda-function.jpg

❖ http://www.ibm.com/developerworks/library/j-jn16/figure1.png

❖ http://www.ibm.com/developerworks/library/j-jn16/figure2.png

❖ http://img.viralpatel.net/2014/01/java-lambda-expression.png

❖ http://www.codercaste.com/wp-content/uploads/2011/01/animals.png

❖ http://blog.takipi.com/wp-content/uploads/2014/03/blog_lambada_2.png

❖ http://quotespictures.com/wp-content/uploads/2014/01/it-is-not-the-strongest-of-the-species-that-survive-nor-the-most-intelligent-but-the-one-most-responsive-to-change-charles-darwin.jpg

❖ http://7-themes.com/data_images/out/27/6859733-surfing-wallpaper.jpg

top related