$30 off During Our Annual Pro Sale. View Details »

Java: Did you Know that?

Java: Did you Know that?

Jeanne Boyarsky

February 20, 2020
Tweet

More Decks by Jeanne Boyarsky

Other Decks in Programming

Transcript

  1. @jeanneboyarsky 1
    Java: Did You Know That?
    Jeanne Boyarsky
    Thursday February 20, 2020
    DevNexus
    speakerdeck.com/boyarsky

    View Slide

  2. @jeanneboyarsky
    About Me
    • Java Champion
    • Author
    • Developer at
    NYC bank for
    17+ years
    • FIRST Robotics
    Mentor
    2

    View Slide

  3. @jeanneboyarsky
    Pause for a Commercial
    3
    Java 11 certs
    •1Z0-815 - Out now
    •1Z0-816 - April ETA

    View Slide

  4. @jeanneboyarsky
    With Contributions By
    • Janeice DelVecchio
    • Elena Felder
    • Scott Selikoff
    4

    View Slide

  5. @jeanneboyarsky
    Removing in a Loop
    5

    View Slide

  6. @jeanneboyarsky
    Removing in a Loop
    6
    List list = new ArrayList<>();
    list.add("red");
    list.add("alliance");
    list.add(“blue");
    list.add("alliance");
    for(String current : list) {
    list.remove(current);
    }
    System.out.println(list);
    Output:
    ConcurrentModificationException

    View Slide

  7. @jeanneboyarsky
    Removing in a Loop
    7
    List list = new ArrayList<>();
    list.add("red");
    list.add("alliance");
    for(String current : list) {
    list.remove(current);
    }
    System.out.println(list);
    Output:
    [alliance]

    View Slide

  8. @jeanneboyarsky
    Behavior Explanation
    8
    1.List starts as [red, alliance]
    2.First iteration through loop,
    current = red
    3.In loop, remove red
    4.Now list is [alliance]
    5.For loop checks size.
    6.Size = 1; already saw one
    element
    7.Done!

    View Slide

  9. @jeanneboyarsky
    Behavior Explanation
    9
    1.vs List as [red, alliance, blue,
    alliance]
    2.Size = 3 after removal and
    saw one
    3.Not Done!
    4.Exception

    View Slide

  10. @jeanneboyarsky
    Removing in a Loop
    10
    List list
    = new CopyOnWriteArrayList<>();
    list.add("red");
    list.add("alliance");
    list.add("blue");
    list.add("alliance");
    for(String current : list) {
    list.remove(current);
    }
    System.out.println(list);
    Output:
    []

    View Slide

  11. @jeanneboyarsky
    Or ditch the loop
    11
    list.clear();
    (or)
    list.removeIf(x -> true);
    Output:
    []

    View Slide

  12. @jeanneboyarsky
    Creating a Set
    12

    View Slide

  13. @jeanneboyarsky
    Creating a Set
    13
    String[] words = { "all", "the", “words",
    "in", "the", "world" };
    Set set = new HashSet<>(
    Arrays.asList(words));
    System.out.println(set);
    Output like:
    [all, the, world, in, words]

    View Slide

  14. @jeanneboyarsky
    Creating a Set
    14
    String[] words = { "all", "the", “words",
    "in", "the", "world" };
    Set set = Set.of(words);
    System.out.println(set);
    Output:
    IllegalArgumentException: duplicate element: the

    View Slide

  15. @jeanneboyarsky
    Behavior Explanation
    15
    1.Set.of() takes varargs.
    2.Doc says can’t have duplicates

    View Slide

  16. @jeanneboyarsky
    Backed Collection
    16

    View Slide

  17. @jeanneboyarsky
    Collection
    17
    Map map = new HashMap<>();
    map.put("Braves", "Atlanta");
    map.put("Mets", "NYC");
    Set keys
    = new HashSet<>(map.keySet());
    keys.remove("Mets");
    System.out.println(map);
    {Mets=NYC, Braves=Atlanta}

    View Slide

  18. @jeanneboyarsky
    Collection
    18
    Map map = new HashMap<>();
    map.put("Braves", "Atlanta");
    map.put("Mets", "NYC");
    Set keys = map.keySet();
    keys.remove("Mets");
    System.out.println(map);
    {Braves=Atlanta}

    View Slide

  19. @jeanneboyarsky
    Behavior Explanation
    19
    1.keySet(), values(), and
    entrySet() are backed
    collections
    2.When change any, it affects
    original map

    View Slide

  20. @jeanneboyarsky
    Overloading
    20

    View Slide

  21. @jeanneboyarsky
    Overloading
    21
    public void check(Number number) {
    System.out.print(“Number "); }
    public void check(Integer integer) {
    System.out.print(“Integer "); }
    public void delegator(Number number) {
    check(number); }
    Integer num = Integer.valueOf(42);
    Overloading target = new Overloading();
    target.check(num);
    target.delegator(num);
    Output:
    Integer Number

    View Slide

  22. @jeanneboyarsky
    Overloading
    22
    public void check(Number number) {
    System.out.print(“Number "); }
    public void check(Integer integer) {
    System.out.print(“Integer "); }
    public void delegator(Number number) {
    check(number); }
    Number num = Integer.valueOf(42);
    Overloading target = new Overloading();
    target.check(num);
    target.delegator(num);
    Output:
    Number Number

    View Slide

  23. @jeanneboyarsky
    Behavior Explanation
    23
    1.Method chosen at compile time,
    not runtime.
    2.(vs polymorphism on objects)

    View Slide

  24. @jeanneboyarsky
    ==
    24

    View Slide

  25. @jeanneboyarsky
    Equality
    25
    Integer int1 = Integer.valueOf(8);
    Integer int2 = Integer.valueOf(8);
    System.out.println((int1 == int2)
    + " " + int1.equals(int2));
    true true

    View Slide

  26. @jeanneboyarsky
    Equality
    26
    Integer int1 = Integer.valueOf(8_000);
    Integer int2 = Integer.valueOf(8_000);
    System.out.println((int1 == int2)
    + " " + int1.equals(int2));
    false true

    View Slide

  27. @jeanneboyarsky
    Behavior Explanation
    27
    1.Wrapper classes cache small
    values
    2.Lesson: always use equals() for
    objects

    View Slide

  28. @jeanneboyarsky
    var and inference
    28

    View Slide

  29. @jeanneboyarsky
    var and inference
    29
    List x1 = List.of();
    List x2 = List.of(1, 2, 3);
    Stream.of(x1, x2)
    .flatMap(x -> x.stream())
    .map(x -> x + 1)
    .forEach(System.out::print);
    Output:
    234

    View Slide

  30. @jeanneboyarsky
    var and inference
    30
    List x1 = List.of();
    var x2 = List.of(1, 2, 3);
    Stream.of(x1, x2)
    .flatMap(x -> x.stream())
    .map(x -> x + 1)
    .forEach(System.out::print);
    Output:
    234

    View Slide

  31. @jeanneboyarsky
    var and inference
    31
    var x1 = List.of();
    var x2 = List.of(1, 2, 3);
    Stream.of(x1, x2)
    .flatMap(x -> x.stream())
    .map(x -> x + 1)
    .forEach(System.out::print);
    Compiler error:
    Operator ‘+’ cannot be applied to capture>, int

    View Slide

  32. @jeanneboyarsky
    Behavior Explanation
    32
    1.var x2 = List.of(1,2,3)
    2.x2 is a List
    3.var x1 = List.of()
    4.x1 is a not a List
    5.Stream.of(x1, x2) is a
    Stream>
    6.flatMap makes Stream
    extends Object>
    7.Object doesn’t go with +

    View Slide

  33. @jeanneboyarsky
    Sorting Characters
    33

    View Slide

  34. @jeanneboyarsky
    Sorting Characters
    34
    Stream ohMy = Stream.of(
    "lions", "tigers", "bears");
    Comparator c =
    Comparator.naturalOrder();
    System.out.println(ohMy.collect(
    Collectors.groupingBy(String::length,
    Collectors.mapping(s ->
    s.charAt(0), Collectors.minBy(c)))));
    Output:
    {5=Optional[b], 6=Optional[t]}

    View Slide

  35. @jeanneboyarsky
    Sorting Characters
    35
    Stream ohMy = Stream.of(
    "lions", "tigers", "bears");
    System.out.println(ohMy.collect(
    Collectors.groupingBy(String::length,
    Collectors.mapping(s ->
    s.charAt(0), Collectors.minBy(
    Comparator.naturalOrder())))));
    Compiler error
    No suitable method found for….

    View Slide

  36. @jeanneboyarsky
    The actual message
    36
    Error:(18, 51) java: no suitable method found for
    groupingBy(String::length,java.util.stream.Collector.Object,capture#1 of ?,java.util.Optional>)
    method
    java.util.stream.Collectors.groupingBy(java.util.function.
    Function super T,? extends K>) is not applicable
    (cannot infer type-variable(s) T,K
    (actual and formal argument lists differ in length))
    method
    java.util.stream.Collectors.groupingBy(java.util.func
    tion.Function super T,? extends
    K>,java.util.stream.Collector super T,A,D>) is not
    applicable
    (inference variable U has incompatible upper bounds
    java.lang.Object,java.lang.Comparable super T>,T,T)…

    View Slide

  37. @jeanneboyarsky
    The other message
    37
    Error:(19, 52) java: cannot find symbol
    symbol: method charAt(int)
    location: variable s of type java.lang.Object

    View Slide

  38. @jeanneboyarsky
    Behavior Explanation
    38
    1.char != Character

    Inferred type check fails
    2.Propagates error to other call
    3.But, this suggests a
    workaround…

    View Slide

  39. @jeanneboyarsky
    Sorting Characters
    39
    Stream ohMy = Stream.of(
    "lions", "tigers", "bears");
    System.out.println(ohMy.collect(
    Collectors.groupingBy(String::length,
    Collectors.mapping((String s) ->
    s.charAt(0), Collectors.minBy(
    Comparator.naturalOrder())))));
    Output:
    {5=Optional[b], 6=Optional[t]}

    View Slide

  40. @jeanneboyarsky
    URL Equality
    40

    View Slide

  41. @jeanneboyarsky
    URL Equality
    41
    URL url1 = new URL("https://google.com");
    URL url2 = new URL("https://google.com");
    System.out.println(url1.equals(url2));
    Output:
    true

    View Slide

  42. @jeanneboyarsky
    URL Equality
    42
    URL url1 = new URL("cloudURL");
    URL url2 = new URL(“cloudURL");
    System.out.println(url1.equals(url2));
    Output:
    false if DNS resolution changes during program

    View Slide

  43. @jeanneboyarsky
    Behavior Explanation
    43
    1.URL’s equals method calls the
    URLStreamHandler’s equals
    method
    2.Which uses DNS resolution
    3.Cloud URLs change often
    Instead, use URI
    https://news.ycombinator.com/
    item?id=21765788

    View Slide

  44. @jeanneboyarsky
    Week of the Year
    44

    View Slide

  45. @jeanneboyarsky
    Week of Year
    45
    LocalDate xmasEve = LocalDate.of(
    2019, Month.DECEMBER, 24);
    WeekFields weekFields = WeekFields.of(
    Locale.getDefault());
    int weekNumber = xmasEve.get(
    weekFields.weekOfWeekBasedYear());
    int week = xmasEve.get(
    weekFields.weekOfYear());
    System.out.println(weekNumber
    + " " + week);
    Output:
    52 52

    View Slide

  46. @jeanneboyarsky
    Week of Year
    46
    LocalDate newYearsEve = LocalDate.of(
    2019, Month.DECEMBER, 31);
    WeekFields weekFields = WeekFields.of(
    Locale.getDefault());
    int weekNumber = newYearsEve.get(
    weekFields.weekOfWeekBasedYear());
    int week = newYearsEve.get(
    weekFields.weekOfYear());
    System.out.println(weekNumber
    + " " + week);
    Output:
    1 53

    View Slide

  47. @jeanneboyarsky
    Behavior Explanation
    47
    1.Most years are 52 weeks + 1
    day
    2.2020 started on a Wednesday.
    3.The week based week starts
    the Sunday before
    4.Whereas weekOfYear() returns
    1-54

    View Slide

  48. @jeanneboyarsky
    Week of Year
    48
    LocalDate xmasEve = LocalDate.of(
    2019, Month.DECEMBER, 24);
    DateTimeFormatter format =
    DateTimeFormatter.ofPattern(
    "yyyy-MM-dd");
    DateTimeFormatter format2 =
    DateTimeFormatter.ofPattern(
    "YYYY-MM-dd");
    System.out.println(xmasEve.format(format)
    + " " + xmasEve.format(format2));
    Output:
    2019-12-24 2019-12-24

    View Slide

  49. @jeanneboyarsky
    Week of Year
    49
    LocalDate newYearsEve = LocalDate.of(
    2019, Month.DECEMBER, 31);
    DateTimeFormatter format =
    DateTimeFormatter.ofPattern(
    "yyyy-MM-dd");
    DateTimeFormatter format2 =
    DateTimeFormatter.ofPattern(
    "YYYY-MM-dd");
    System.out.println(
    newYearsEve.format(format) + " "
    + newYearsEve.format(format2));
    Output:
    2019-12-31 2020-12-31

    View Slide

  50. @jeanneboyarsky
    Behavior Explanation
    50
    1.y is year
    2.Y is week of year
    3.Be careful with week of year!

    View Slide

  51. @jeanneboyarsky
    Closing Resources
    51

    View Slide

  52. @jeanneboyarsky
    JDBC
    52
    PreparedStatement stmt =
    conn.prepareStatement(
    "update mytable set updated = now()");
    try (stmt) {
    stmt.executeUpdate();
    }
    “Good”

    View Slide

  53. @jeanneboyarsky
    JDBC
    53
    PreparedStatement stmt =
    conn.prepareStatement(
    "update mytable set updated = now()" +
    " where key = ?");
    stmt.setString(1, "abc");
    try (stmt) {
    stmt.executeUpdate();
    }
    Resource leak!

    View Slide

  54. @jeanneboyarsky
    Behavior Explanation
    54
    1.What happens if an exception is
    thrown while calling the
    PreparedStatement setter?
    2.The try-with-resources doesn’t
    run
    3.Resource leak!

    View Slide

  55. @jeanneboyarsky
    JDBC
    55
    PreparedStatement stmt =
    conn.prepareStatement(
    "update mytable set updated = now()" +
    " where key = ?");
    try (stmt) {
    stmt.setString(1, "abc");
    stmt.executeUpdate();
    }
    “good”

    View Slide

  56. @jeanneboyarsky
    IO
    56
    try (BufferedReader reader =
    Files.newBufferedReader(path)) {
    String line = null;
    while
    ((line = reader.readLine())!= null) {
    // process line
    }
    }
    No leak

    View Slide

  57. @jeanneboyarsky
    IO
    57
    Files.lines(path).count();
    Resource leak!

    View Slide

  58. @jeanneboyarsky
    Behavior Explanation
    58
    1.Resource not closed by
    terminal operation
    2.Affects
    1.find()
    2.lines()
    3.list()
    4.newDirectoryStream()
    5.walk()

    View Slide

  59. @jeanneboyarsky
    IO
    59
    try (Stream stream
    = Files.lines(path)) {
    stream.count();
    }
    Good

    View Slide

  60. @jeanneboyarsky
    PSA: Free Tools
    •PMD
    •FindBugs
    •CheckStyle
    •SonarQube - examples:
    •No return in finally
    •Close resources
    •All sorts of bugs
    60

    View Slide

  61. @jeanneboyarsky
    Other Favorites?
    ???
    61

    View Slide