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.

Pattern Matching in Java 14

475 views

Published on

This webinar by Oleksandr Navka (Lead Software Engineer, Consultant, GlobalLogic) was delivered at Java Community Webinar #1 on August 12, 2020.

Webinar agenda:
- The new structural unit of the program is Java Records
- Updated instanceof statement
- Updated switch operator

More details and presentation: https://www.globallogic.com/ua/about/events/java-community-webinar-1/

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Pattern Matching in Java 14

  1. 1. 1 Java 14 Pattern Matching Oleksandr Navka Lead Software Engineer, Consultant, GlobalLogic
  2. 2. 2 1. Updated instanceof 2. Updated switch-case 3. Java Records Agenda
  3. 3. 3 Тагир Валеев JetBrains Pattern matching и его воображаемые друзья
  4. 4. 4
  5. 5. 5 When someone match something :) What is pattern matching?
  6. 6. 6 Any pattern • _ Constant pattern • 1 • true • null Type pattern • String s Var pattern • var i = 1 Deconstruction pattern • Optional(String s) • Node(Node left, Node right) What are the patterns?
  7. 7. 7 Instanceof
  8. 8. 8 public class Animal { } class Dog extends Animal { public void bark() { } } class Cat extends Animal { public void meow() { } }
  9. 9. 9 public static void say(Animal animal) { if (animal instanceof Dog) { Dog dog = (Dog) animal; dog.bark(); } else if (animal instanceof Cat) { Cat cat = (Cat) animal; cat.meow(); } }
  10. 10. 10 public static void say(Animal animal) { if (animal instanceof Dog) { Dog dog = (Dog) animal; dog.bark(); } else if (animal instanceof Cat) { Cat cat = (Cat) animal; cat.meow(); } }
  11. 11. 11 public static void say(Animal animal) { if (animal instanceof Dog dog) { dog.bark(); } else if (animal instanceof Cat cat) { cat.meow(); } }
  12. 12. 12 public static void say(Animal animal) { if (animal instanceof Dog dog) { dog.bark(); } else if (animal instanceof Cat cat) { cat.meow(); } }
  13. 13. 13 Before: expression istanceof Type Now: expression instanceof Pattern
  14. 14. 14 Scoping
  15. 15. 15 if (obj instanceof String s) { // can use s here } else { // can't use s here }
  16. 16. 16 if (obj instanceof String s) { // can use s here } else { // can't use s here } binding variable
  17. 17. 17 if (!(obj instanceof String s)) { } else { s.contains("a") }
  18. 18. 18 if(obj instanceof String s && s.length() > 5) { System.out.println(s.toUpperCase()); }
  19. 19. 19 if(obj instanceof String s || s.length() > 5) { System.out.println(s.toUpperCase()); }
  20. 20. 20 if(!(obj instanceof String s) || s.length() > 5) { System.out.println("Do something"); } else { System.out.println(s.toUpperCase()); }
  21. 21. 21 if(!(obj instanceof String s) || s.length() > 5) { System.out.println("Do something"); } else { System.out.println(s.toUpperCase()); }
  22. 22. 22 if(!(obj instanceof String s) || s.length() > 5) { throw new IllegalArgumentException(); } System.out.println(s.toUpperCase());
  23. 23. 23 if(!(obj instanceof String s) || s.length() > 5) { throw new IllegalArgumentException(); } System.out.println(s.toUpperCase());
  24. 24. 24 if (!(obj instanceof String s)) { s.contains(..) } else { s.contains(..) }
  25. 25. 25 private String s = "abc"; if (!(obj instanceof String s)) { s.contains(..) } else { s.contains(..) }
  26. 26. 26 1. if (obj instanceof String s) {s.trim()} 2. if (!(obj instanceof String s)) {} else {s.contains("a")} 3. if(obj instanceof String s && s.length() > 5) {} 4. if(obj instanceof String s || s.length() > 5) {} Binding variable scope
  27. 27. 27 1. if (obj instanceof String s) {s.trim()} 2. if (!(obj instanceof String s)) {} else {s.contains("a")} 3. if(obj instanceof String s && s.length() > 5) {} 4. if(obj instanceof String s || s.length() > 5) {} Binding variable scope
  28. 28. 28 1. if (obj instanceof String s) {s.trim()} 2. if (!(obj instanceof String s)) {} else {s.contains("a")} 3. if(obj instanceof String s && s.length() > 5) {} 4. if(obj instanceof String s || s.length() > 5) {} 5. if(!(obj instanceof String s) || s.length() > 5) {} 6. if(!(obj instanceof String s) || s.length() > 5) {} else {s.toUpperCase());} 7. if(!(obj instanceof String s) || s.length() > 5) { throw new IllegalArgumentException(); } System.out.println(s.toUpperCase()); Binding variable scope
  29. 29. 29 1. instanceof has got type pattern matching 2. instanceof the first java feature that got pattern matching 3. Be aware about scoping Instanceof Summary
  30. 30. 30 Switch - case
  31. 31. 31 public enum ProgrammingParadigm {OBJECT_ORIENTED, PROCEDURAL, FUNCTIONAL} public static List<String> getProgrammingLanguage(ProgrammingParadigm programmingParadigm) { List<String> languages = new ArrayList<>(); switch (programmingParadigm) { case OBJECT_ORIENTED: languages.add("Java"); languages.add("C++"); break; case FUNCTIONAL: languages.add("Haskel"); break; case PROCEDURAL: languages.add("Pascal"); break; } return languages; } Old version of switch
  32. 32. 32 public enum ProgrammingParadigm {OBJECT_ORIENTED, PROCEDURAL, FUNCTIONAL} public static List<String> getProgrammingLanguage(ProgrammingParadigm programmingParadigm) { List<String> languages = new ArrayList<>(); switch (programmingParadigm) { case OBJECT_ORIENTED: languages.add("Java"); languages.add("C++"); break; case FUNCTIONAL: languages.add("Haskel"); break; case PROCEDURAL: languages.add("Pascal"); break; } return languages; } Old version of switch
  33. 33. 33 public enum ProgrammingParadigm {OBJECT_ORIENTED, PROCEDURAL, FUNCTIONAL} public static List<String> getProgrammingLanguage(ProgrammingParadigm programmingParadigm) { List<String> languages = new ArrayList<>(); switch (programmingParadigm) { case OBJECT_ORIENTED: languages.add("Java"); languages.add("C++"); break; case FUNCTIONAL: languages.add("Haskel"); break; case PROCEDURAL: languages.add("Pascal"); break; } return languages; } Old version of switch Input type limitations: byte, short, char, and int Enum Types, String
  34. 34. 34 public enum ProgrammingParadigm {OBJECT_ORIENTED, PROCEDURAL, FUNCTIONAL} public static List<String> getProgrammingLanguage(ProgrammingParadigm programmingParadigm) { List<String> languages = new ArrayList<>(); switch (programmingParadigm) { case OBJECT_ORIENTED: languages.add("Java"); languages.add("C++"); break; case FUNCTIONAL: languages.add("Haskel"); break; case PROCEDURAL: languages.add("Pascal"); break; } return languages; } Old version of switch Can’t get result
  35. 35. 35 public static List<String> getProgrammingLanguage(ProgrammingParadigm programmingParadigm) { switch (programmingParadigm) { case OBJECT_ORIENTED: return List.of("Java", "C++"); case FUNCTIONAL: return List.of("Haskel"); case PROCEDURAL: return List.of("Pascal"); default: return List.of(); } }
  36. 36. 36 public static List<String> getProgrammingLanguage(ProgrammingParadigm programmingParadigm) { switch (programmingParadigm) { case OBJECT_ORIENTED: return List.of("Java", "C++"); case FUNCTIONAL: return List.of("Haskel"); case PROCEDURAL: return List.of("Pascal"); default: return List.of(); } }
  37. 37. 37 Disadvantages: 1. Always remember about break 2. Input data type limitation 3. Can’t get result 4. Don’t understand all possible options for enum Old version of switch
  38. 38. 38 Pattern matching with switch case
  39. 39. 39 public void printObject(Object obj) { switch (obj) { case String s: System.out.println("This is String" + s.trim()); break; case Integer i: System.out.println("This is Integer" + i); break; case Number n: System.out.println("This is number"+ n); break; default: System.out.println("I don't know"); } }
  40. 40. 40 public void printObject(Object obj) { switch (obj) { case String s: System.out.println("This is String" + s.trim()); break; case Number n: System.out.println("This is number"+ n); break; case Integer i: System.out.println("This is Integer" + i); break; default: System.out.println("I don't know"); } }
  41. 41. 41 public void printObject(Object obj) { switch (obj) { case String s: System.out.println("This is String" + s.trim()); break; default: System.out.println("I don't know"); case Number n: System.out.println("This is number"+ n); break; case Integer i: System.out.println("This is Integer" + i); break; } }
  42. 42. 42 Updated switch case
  43. 43. 43 public static List<String> getProgrammingLanguage(ProgrammingParadigm programmingParadigm) { return switch (programmingParadigm) { case OBJECT_ORIENTED -> List.of("Java", "C++"); case FUNCTIONAL -> List.of("Haskel"); case PROCEDURAL -> List.of("Pascal"); }; } Updated switch case
  44. 44. 44 public static List<String> getProgrammingLanguage(ProgrammingParadigm programmingParadigm) { return switch (programmingParadigm) { case OBJECT_ORIENTED -> { System.out.println("You are master of polymorphism"); yield List.of("Java", "C++"); } case FUNCTIONAL -> { System.out.println("You are master of recursion"); yield List.of("Haskel"); } case PROCEDURAL -> { System.out.println("Try to use another paradigms"); yield List.of("Pascal"); } }; }
  45. 45. 45 1. Don’t need to use break 2. Can return result 3. Don’t need to use default branch if all options described 4. Input data types have limitations Summary of updated switch
  46. 46. 46 Java Records
  47. 47. 47 private record Car(int speed, String manufacturer) { } Java Records
  48. 48. 48 private record Car(int speed, String manufacturer) { } public static void main(String[] args) { Car car = new Car(100, "Mercedes"); System.out.println(car.speed()); System.out.println(car.manufacturer()); } Java Records
  49. 49. 49 private record Car(int speed, String manufacturer) { } public static void main(String[] args) { Car car = new Car(100, "Mercedes"); System.out.println(car); } ------- Output: Car[speed=100, manufacturer=Mercedes] Java Records
  50. 50. 50 private static final class Car extends java.lang.Record { private final int speed; private final java.lang.String manufacturer; public Car(int speed, java.lang.String manufacturer) { /* compiled code */ } public java.lang.String toString() { /* compiled code */ } public final int hashCode() { /* compiled code */ } public final boolean equals(java.lang.Object o) { /* compiled code */ } public int speed() { /* compiled code */ } public java.lang.String manufacturer() { /* compiled code */ } }
  51. 51. 51 private static final class Car extends java.lang.Record { private final int speed; private final java.lang.String manufacturer; public Car(int speed, java.lang.String manufacturer) { /* compiled code */ } public java.lang.String toString() { /* compiled code */ } public final int hashCode() { /* compiled code */ } public final boolean equals(java.lang.Object o) { /* compiled code */ } public int speed() { /* compiled code */ } public java.lang.String manufacturer() { /* compiled code */ } }
  52. 52. 52 public abstract class Record { protected Record() {} @Override public abstract boolean equals(Object obj); @Override public abstract int hashCode(); @Override public abstract String toString(); }
  53. 53. 53 private static final class Car extends java.lang.Record { private final int speed; private final java.lang.String manufacturer; public Car(int speed, java.lang.String manufacturer) { /* compiled code */ } public java.lang.String toString() { /* compiled code */ } public final int hashCode() { /* compiled code */ } public final boolean equals(java.lang.Object o) { /* compiled code */ } public int speed() { /* compiled code */ } public java.lang.String manufacturer() { /* compiled code */ } }
  54. 54. 54 private static final class Car extends java.lang.Record { private final int speed; private final java.lang.String manufacturer; public Car(int speed, java.lang.String manufacturer) { /* compiled code */ } public java.lang.String toString() { /* compiled code */ } public final int hashCode() { /* compiled code */ } public final boolean equals(java.lang.Object o) { /* compiled code */ } public int speed() { /* compiled code */ } public java.lang.String manufacturer() { /* compiled code */ } }
  55. 55. 55 private record Car(int speed, String manufacturer) { public Car { if(speed < 0) { throw new IllegalArgumentException(); } } } public static void main(String[] args) { var car = new Car(-2, "Mercedes"); System.out.println(car); } Canonical constructor
  56. 56. 56 private record Car(int speed, String manufacturer) { public Car { if(speed < 0) { throw new IllegalArgumentException(); } } public Car(String manufacturer) { this(0, manufacturer); } } Canonical constructor
  57. 57. 57 private static final class Car extends java.lang.Record { private final int speed; private final java.lang.String manufacturer; public Car(int speed, java.lang.String manufacturer) { /* compiled code */ } public java.lang.String toString() { /* compiled code */ } public final int hashCode() { /* compiled code */ } public final boolean equals(java.lang.Object o) { /* compiled code */ } public int speed() { /* compiled code */ } public java.lang.String manufacturer() { /* compiled code */ } }
  58. 58. 58 private static final class Car extends java.lang.Record { private final int speed; private final java.lang.String manufacturer; public Car(int speed, java.lang.String manufacturer) { /* compiled code */ } public java.lang.String toString() { /* compiled code */ } public final int hashCode() { /* compiled code */ } public final boolean equals(java.lang.Object o) { /* compiled code */ } public int speed() { /* compiled code */ } public java.lang.String manufacturer() { /* compiled code */ } }
  59. 59. 59 1. Java 14 present first version of pattern matching 2. Type pattern matching present in instanceof operator 3. New Switch statement was released with some blanks for pattern matching 4. Keep eye on Java Records and deconstruction patterns Summary
  60. 60. 60 Thank You

×