Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Functional Programming in Java 8 - Lambdas and Streams

Presentation that covers lambdas, functional interfaces, streams and more!

  • Be the first to comment

  • Be the first to like this

Functional Programming in Java 8 - Lambdas and Streams

  1. 1. Functional Programming Lambdas & Streams GANESH & HARI CODEOPS TECHNOLOGIES ganesh@codeops.tech hari@codeops.tech
  2. 2. Adapt: Learn functional programming
  3. 3. Agenda • Introduction & Overview • Lambdas • Functional interfaces • Streams • Parallel Streams • Date & Time package • Refactoring to Java 8
  4. 4. Java meets functional programming (with lambdas)
  5. 5. Java is not your grandma’s language anymore!
  6. 6. Greek characters are scary!
  7. 7. He he, but lambdas are fun, not scary
  8. 8. List<String> strings = Arrays.asList("eeny", "meeny", "miny", "mo") ; Consumer<String> printString = string -> System.out.println(string); strings.forEach(printString) ; Lambda functions!
  9. 9. But what are lambdas?
  10. 10. Lambdas is just a fancy name for functions without a name!
  11. 11. 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 clas s ❖ They don’t change external state
  12. 12. 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’ input s ❖ Underlying approach: “Evaluate an expression. Then use the results for something else.”
  13. 13. Perspective - for loops! List<String> strings = Arrays.asList("eeny", "meeny", "miny", "mo") ; for(String string : strings){ System.out.println(string) ; } External Iteration
  14. 14. Perspective - for loops! List<String> strings = Arrays.asList("eeny", "meeny", "miny", "mo") ; strings.forEach(string -> System.out.println(string)) ; Internal Iteration
  15. 15. 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
  16. 16. 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
  17. 17. You can use lambdas for some amazing stuff
  18. 18. sedime nt pre- carbon ultra- fi lter post- carbon Filtered water E.g., you can compose lambda functions as in pipes-and- fi lters
  19. 19. $ 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.
  20. 20. $ 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
  21. 21. 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
  22. 22. Lambdas & streams help in productive programming!
  23. 23. 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
  24. 24. Java 8 is the new Groovy ;-) import java.io.*; class Type { public sta ti c void main(String [] fi les) { // process each fi le passed as argument for(String fi le : fi les) { // try opening the fi le with FileReader try (FileReader inputFile = new FileReader( fi le)) { int ch = 0; while( (ch = inputFile.read()) != -1) { // ch is of type int - convert it back to char System.out.print( (char)ch ); } } catch (FileNotFoundExcep ti on fnfe) { System.err.prin tf ("Cannot open the given fi le %s ", fi le); } catch(IOExcep ti on ioe) { System.err.prin tf ("Error when processing fi le %s; skipping it", fi le); } // try-with-resources will automa ti cally release FileReader object } } } args.each { println new File(it).getText() }
  25. 25. Streams package in Java 8
  26. 26. Java library “enhanced” with streams
  27. 27. Agenda • Introduction & Overview • Lambdas • Functional interfaces • Streams • Parallel streams • Date & Time package • Refactoring to Java 8
  28. 28. 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(); } }
  29. 29. 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
  30. 30. 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
  31. 31. Method references Method references - “syntactic sugar” for lambda functions They “route” function parameters arg -> System.out.println(arg) System.out::println
  32. 32. 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);
  33. 33. 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
  34. 34. 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);
  35. 35. “Effectively final” variables import java.util.Arrays ; import java.util.List; class PigLatin { public static void main(String []args) { String suf fi x = "ay"; List<String> strings = Arrays.asList("one", "two", "three", "four") ; strings.forEach(string -> System.out.println(string + suf fi x)); } } Accessing “local variable” suf fi x here; hence it is considered “effectively fi nal”
  36. 36. “Effectively final” variables import java.util.Arrays ; import java.util.List; class PigLatin { public static void main(String []args) { String suf fi x = "ay"; List<String> strings = Arrays.asList("one", "two", "three", “four") ; suf fi x = "e"; // assign to suf fi x variable strings.forEach(string -> System.out.println(string + suf fi x)); } } 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
  37. 37. Agenda • Introduction & Overview • Lambdas • Functional interfaces • Streams • Parallel streams • Date & Time package • Refactoring to Java 8
  38. 38. Functional interfaces @FunctionalInterfac e 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
  39. 39. Java 8 lambdas - “Hello world!” @FunctionalInterfac e 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
  40. 40. 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); }
  41. 41. Functional interfaces: Single abstract methods @FunctionalInterfac e interface LambdaFunction { void call(); // Single Abstract Method (SAM ) }
  42. 42. 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 @FunctionalInterfac e public interface Consumer<T> { void accept(T t) ; // the default andThen method elided }
  43. 43. 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)) ;
  44. 44. Default methods in interfaces public 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()) ; } }
  45. 45. “Diamond” inheritance problem?
  46. 46. “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 Interface 2
  47. 47. “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 de fi nition to resolve the ambiguity
  48. 48. “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
  49. 49. Built-in functional interfaces
  50. 50. Built-in functional interfaces are a part of the java.util.function package (in Java 8)
  51. 51. Built-in interfaces Predicate<T> Checks a condition and returns a boolean value as result In fi lter() 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) asConsumer<T> Operation that takes an argument but returns nothing In forEach() method in collections and in java.util.stream.Stream; this method is used for traversing all the elements in the collection orFunction<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 in fi nite stream of elements.
  52. 52. Predicate interface Stream.of("hello", "world" ) . fi lter(str -> str.startsWith("h") ) .forEach(System.out::println); The fi lter() method takes a Predicate as an argument (predicates are functions that check a condition and return a boolean value)
  53. 53. Predicate interface
  54. 54. Predicate interface A Predicate<T> “af fi rms” 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. @FunctionalInterfac e public interface Predicate<T> { boolean test(T t) ; // other methods elide d }
  55. 55. 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: tru e false
  56. 56. 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
  57. 57. Consumer interface Stream.of("hello", "world" ) .forEach(System.out::println) ; // void forEach(Consumer<? super T> action); Prints: hell o world
  58. 58. Consumer interface
  59. 59. 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. @FunctionalInterfac e public interface Consumer<T> { void accept(T t) ; // the default andThen method elide d }
  60. 60. Consumer interface: Example Consumer<String> printUpperCase = str -> System.out.println(str.toUpperCase()) ; printUpperCase.accept("hello"); Prints: HELLO
  61. 61. 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: hell o world
  62. 62. 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: 4 9 16
  63. 63. Function interface
  64. 64. 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. @FunctionalInterfac e public interface Function<T, R> { R apply(T t) ; // other methods elide d }
  65. 65. Function interface: Example Function<String, Integer> strLength = str -> str.length() ; System.out.println(strLength.apply("supercalifragilisticexpialidocious")); Prints: 34
  66. 66. 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: 4 9 16
  67. 67. 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
  68. 68. Supplier interface
  69. 69. 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 @FunctionalInterfac e public interface Supplier<T> { T get() ; // no other methods in this interfac e }
  70. 70. Supplier interface: Example Supplier<String> currentDateTime = () -> LocalDateTime.now().toString() ; System.out.println(currentDateTime.get()); Prints current time: 2015-10-16T12:40:55.164
  71. 71. 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.
  72. 72. Agenda • Introduction & Overview • Lambdas • Functional interfaces • Stream s • Parallel streams • Date & Time package • Refactoring to Java 8
  73. 73. Java 8 streams (and parallel streams) : Excellent example of applying functional programming in practice
  74. 74. But what are streams?
  75. 75. Arrays.stream(Object.class.getMethods()) .map(method -> method.getName()) .distinct() .forEach(System.out::println); wait equals toString hashCode getClass notify notifyAll
  76. 76. 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)
  77. 77. stream pipeline Stream source Intermediate opera1ons Terminal opera1on stream stream Examples: IntStream.range(), Arrays.stream() Examples: map(), filter(), dis1nct(), sorted() Examples: sum(), collect(), forEach(), reduce()
  78. 78. DoubleStream. of(1.0, 4.0, 9.0) map(Math::sqrt) .peek(System.out:: println) Stream Source (with elements 1.0, 4.0, and 9.0) Intermediate Opera=on 1 (maps to element values 1.0, 2.0, and 3.0) Intermediate Opera=on 2 (prints 1.0, 2.0, and 3.0) .sum(); Terminal Opera=on (returns the sum 6.0) DoubleStream.of(1.0, 4.0, 9.0) .map(Math::sqrt) .peek(System.out::println) .sum();
  79. 79. IntStream.range(1, 6 ) You can use range or iterate factory methods in the IntStream interface IntStream.iterate(1, i -> i + 1).limit(5)
  80. 80. 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
  81. 81. 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
  82. 82. stream can be in fi nite IntStream.iterate(0, i -> i + 2).forEach(System.out::println) ; This code creates in fi nite stream of even numbers!
  83. 83. IntStrea m .iterate(0, i -> i + 2) .limit(5 ) .forEach(System.out::println) ; Using the “limit” function to limit the stream to 5 integers
  84. 84. 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
  85. 85. Streams are lazy!
  86. 86. Files.lines(Paths.get("FileRead.java")).forEach(System.out::println); This code prints the contents of the fi le “FileRead.java” in the current directory
  87. 87. 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
  88. 88. new Random().ints().limit(5).forEach(System.out::println); Generates 5 random integers and prints them on the console
  89. 89. "hello".chars().sorted().forEach(ch -> System.out.printf("%c ", ch)); Extracts characters in the string “hello”, sorts the chars and prints the chars
  90. 90. Agenda • Introduction & Overview • Lambdas • Functional interfaces • Streams • Parallel streams • Date & Time package • Refactoring to Java 8
  91. 91. Parallel Streams
  92. 92. race conditions
  93. 93. deadlocks
  94. 94. I really really hate concurrency problems
  95. 95. Parallel code Serial code
  96. 96. Sometimes, dreams do come true even at 86 :-)
  97. 97. So, keep dreaming till you become 86!
  98. 98. long numOfPrimes = LongStream.rangeClosed(2, 100_000) . fi lter(PrimeNumbers::isPrime) .count(); System.out.println(numOfPrimes); Prints 9592 2.510 seconds
  99. 99. Parallel code Serial code Let’s fl ip the switch by calling parallel() function
  100. 100. long numOfPrimes = LongStream.rangeClosed(2, 100_000) .parallel() . fi lter(PrimeNumbers::isPrime) .count(); System.out.println(numOfPrimes); Prints 9592 1.235 seconds
  101. 101. Wow! That’s an awesomefl ip switch!
  102. 102. Internally, parallel streams make use of fork-join framework
  103. 103. 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
  104. 104. Agenda • Introduction & Overview • Lambdas • Functional interfaces • Streams • Parallel streams • Date & Time package • Refactoring to Java 8
  105. 105. –Craig Larman "The critical design tool for software development is a mind well educated in design principles"
  106. 106. Design Smells: Example
  107. 107. 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!
  108. 108. 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?
  109. 109. Joda API JSR 310: Java Date and Time API Stephen Colebourne
  110. 110. Refactoring for Date Replace inheritance with delegation
  111. 111. java.time package! Date, Calendar, and TimeZone Java 8 replaces these types
  112. 112. Refactored Solution LocalDate 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 fi ne now!
  113. 113. 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]
  114. 114. “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 pre fi xes plus and minus to add or subtract date or time values)
  115. 115. java.time Sub-packages ❖ java.time.temporal —Accesses date/time fi elds and unit s ❖ java.time.format —Formats the input and output of date/time object s ❖ java.time.zone —Handles time zone s ❖ java.time.chrono —Supports calendar systems such as Japanese and Thai calendars
  116. 116. 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.
  117. 117. java.time.LocalDate LocalDate newYear2016 = LocalDate.of(2016, 1, 1); System.out.println("New year 2016: " + newYear2016); New year 2016: 2016-01-01
  118. 118. 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
  119. 119. 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
  120. 120. Important Methods in LocalDate
  121. 121. java.time.LocalTime LocalTime currTime = LocalTime.now(); System.out.println("Current time is: " + currTime); Current time is: 12:23:05.072
  122. 122. java.time.LocalTime System.out.println(LocalTime.of(18,30)); prints: 18:30
  123. 123. 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.62 4 My meeting is at: 18:59:13.624
  124. 124. Important Methods in LocalTime
  125. 125. 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
  126. 126. 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
  127. 127. 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.49 7 The date component is: 2015-11-0 4 The time component is: 13:19:10.497
  128. 128. 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.502 Z Number of seconds elapsed: 144643416 4 Number of milliseconds elapsed: 1446434164502
  129. 129. 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)
  130. 130. Important Methods in Period
  131. 131. 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).
  132. 132. 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
  133. 133. Important Methods in Duration
  134. 134. Summary of Instant, Period and Duration
  135. 135. 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 tt %b tt %s %n”, unit, unit.isDateBased(), unit.isTimeBased(), unit.getDuration()); } } }
  136. 136. ZoneId System.out.println("My zone id is: " + ZoneId.systemDefault()); My zone id is: Asia/Kolkata ZoneId AsiaKolkataZoneId = ZoneId.of("Asia/Kolkata");
  137. 137. 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]
  138. 138. 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
  139. 139. ZonedDateTime ZoneId singaporeZone = ZoneId.of(“Asia/Singapore"); ZonedDateTime dateTimeInSingapore = ZonedDateTime.of(LocalDateTime.of(2016, Month.JANUARY, 1, 6, 0), singaporeZone); ZoneId aucklandZone = ZoneId.of("Paci fi c/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 Paci fi c/Auckland zones is 5 hours
  140. 140. 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("Paci fi c/Auckland"); Duration aucklandDST = aucklandZone.getRules().getDaylightSavings(Instant.now()); System.out.printf("Auckland zone DST is: %d hours", aucklandDST.toHours()); Kolkata zone DST is: 0 hour s Auckland zone DST is: 1 hours
  141. 141. 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])
  142. 142. 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)));
  143. 143. Uppercase and lowercase letters can have similar or different meanings when used in format strings fo r dates 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 !
  144. 144. 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)
  145. 145. Custom Date Patterns public 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-201 5 Pattern "d '('E')' MMM, YYYY" is 5 (Thu) Nov, 201 5 Pattern "w'th week of' YYYY" is 45th week of 201 5 Pattern "EEEE, dd'th' MMMM, YYYY" is Thursday, 05th November, 2015
  146. 146. 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)
  147. 147. Custom Time Patterns class 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:2 7 Time in pattern "hh 'o''clock'" is 12 o'cloc k Time in pattern "H:mm a" is 12:27 P M Time in pattern "hh:mm:ss:SS" is 12:27:10:4 1 Time in pattern "K:mm:ss a" is 0:27:10 PM
  148. 148. 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("Paci fi c/Auckland")).plusHours(10); System.out.println("Arrival: " + dateTimeFormatter.format(arrival)); Departure: 01 Jan 2016 06.00 A M Arrival: 01 Jan 2016 09.00 PM
  149. 149. Agenda • Introduction & Overview • Lambdas • Functional interfaces • Streams • Parallel streams • Date & Time package • Refactoring to Java 8
  150. 150. 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 ) ❖ Replace nested if conditions and loops and instead use enhanced stream methods in collections
  151. 151. Refactoring loops to streams ❖ Replace if conditions with stream functions that return boolean value ( fi lter, fi ndFirst, anyMatch, …) ❖ Replace for, while, and do-while loops with stream operations (especially forEach) ❖ Replace accumulation operations with collect, or reduce (or its special forms such as sum, count, etc)
  152. 152. 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); } Exploit enriched Java APIs with lambdas and streams support External iteration (for loop) to internal iteration (forEach in sterams)
  153. 153. // Imperative code in Java String integers = "4, -9, 16"; String []intStrings = integers.split(", "); for(String anInteger: intStrings) { int intValue = Integer.parseInt(anInteger); int absIntValue = (intValue < 0) ? -intValue : intValue; System.out.println(absIntValue); } // Equivalent functional code (using streams library) in Java Arrays.stream("4, -9, 16".split(", ")) .map(Integer::parseInt) .map(intValue -> (intValue < 0) ? -intValue: intValue) .forEach(System.out::println); Function calls and inline code Composing functions (using lambdas)
  154. 154. 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.
  155. 155. 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
  156. 156. Refactoring suggestions in Netbeans Image source: http://refactoring.info/tools/LambdaFicator/
  157. 157. Java 8 Migration Aids in IntelliJ IDEA Image source: https://www.jetbrains.com/help/img/idea/ij_java_8_inspection_results_migration_runnable.png
  158. 158. Java 8 Refactorings in IntelliJ IDEA Image 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
  159. 159. Refactoring suggestions in Netbeans Image source: http://refactoring.info/tools/LambdaFicator/
  160. 160. Refactoring suggestions in Netbeans Image source: http://refactoring.info/tools/LambdaFicator/
  161. 161. 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)
  162. 162. Meetups h tt p://www.meetup.com/CloudOps-Meetup-Bangalore/ (10th June, Citrix) h tt ps://www.meetup.com/Bot-builder-Bangalore/ (17th June, Microso ft ) h tt p://www.meetup.com/Mobile-App-Developers-Bangalore-Meetup/ (24th June, Sedin) h tt p://www.meetup.com/Container-Developers-Meetup-Bangalore/ (8th July, Citrix) h tt p://www.meetup.com/JavaScript-Meetup-Bangalore/ (15th July, IG Group) h tt p://www.meetup.com/Core-Java-Meetup-Bangalore/ (22nd July, PayPal) h tt ps://www.meetup.com/Serverless-Bangalore/ (??)
  163. 163. 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.webtraf fi croi.com/wp-content/uploads/2012/10/mahatma-gandhi-apple-think- different.jpg ❖ http://rexx-language-association-forum.44760.x6.nabble.com/ fi le/n2236/Ruby-lambda-function.jpg ❖ http://www.ibm.com/developerworks/library/j-jn16/ fi gure1.png ❖ http://www.ibm.com/developerworks/library/j-jn16/ fi gure2.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-sur fi ng-wallpaper.jpg
  164. 164. ganesh@codeops.tech @GSamarthyam www.codeops.tech slideshare.net/sgganesh +91 98801 64463 bit.ly/sgganesh

×