Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[JDD] Java 8 - what could possibly go wrong?

[JDD] Java 8 - what could possibly go wrong?

Slides from JDD presentation "Java 8 - what could possibly go wrong?" (http://16.jdd.org.pl/program/lecture/java-8-what-could-possibly-go-wrong/).

Grzegorz Rożniecki

October 11, 2016
Tweet

More Decks by Grzegorz Rożniecki

Other Decks in Programming

Transcript

  1. About me @xaerxess Important: Images used in this presentation (and

    the presentation itself) are free to use under Creative Commons Attribution License. Code (reviews) addict Open Source advocate I’m a software engineer who enjoys learning and likes sharing his knowledge. Big GNU/Linux fan and Open Source Software advocate. I’ve developed software in various languages, including Perl, JavaScript, Java, Python, PHP and Lisp (and experimented with few others). • Being a programmer is mostly reading code, not writing • You are not your code! • Freedom is important • You can read how libraries, languages, even operating systems are built - and learn! • Contribute, it’s easy!
  2. Java 8 adoption Java versions as of March 2016 October

    2014 27% 38% 64% May 2015 March 2016
  3. Programming styles Imperative Declarative Functional The focus is on what

    steps the computer should take rather than what the computer will do (ex. C, C++, Java). The focus is on what the computer should do rather than how it should do it (ex. SQL). A subset of declarative languages that has heavy focus on recursion.
  4. Streams java.util.stream Classes in the new java.util.stream package provide a

    Stream API to support functional-style operations on streams of elements. The Stream API is integrated into the Collections API, which enables bulk operations on collections, such as sequential or parallel map-reduce transformations. • Sequential • Parallel • Unordered? “ ”
  5. Parallel streams Tasks in ForkJoinPool into smaller pieces split new

    subtasks fork computed tasks join 1 2 3 4 results from pieces compose
  6. Parallel streams List<Integer> primes = IntStream .range(1, 1_000_000) .parallel() .filter(PrimesPrint::isPrime)

    .collect(toList()); // how many threads is this using? // how do I configure that? Defaults // see ForkJoinPool Javadoc -Djava.util.concurrent.ForkJoinPool.common.parallelism=4
  7. Parallel streams ForkJoinPool forkJoinPool = new ForkJoinPool(2); forkJoinPool.submit(() -> IntStream.range(1,

    1_000_000).parallel() .filter(PrimesPrint::isPrime) .collect(toList()) ).get(); Custom ForkJoinPool
  8. Libraries jOOL / jOOλ StreamEx Javaslang • Almost drop-in replacement

    (extension) of Stream • Only sequential • SQL-like collectors • Adds TupleN, FunctionN • More goodies than in jOOL • Also parallel and primitive streams • Even MoreCollectors • Adds TupleN, FunctionN • “Go functional” • Fully functional library for Java 8+ • Adds functional collection library • Adds TupleN, FunctionN and much more (vide currying)
  9. Problem static final ImmutableList<String> DATA = ImmutableList.of("foo", "bar", "baz", "bazinga");

    static final String[] ARRAY_DATA = DATA.stream().toArray(String[]::new); static final Iterable<String> ITERABLE_DATA = DATA; static final Iterator<String> ITERATOR_DATA = DATA.iterator(); // don't do this at home or work! How create Stream? DATA.stream(); Arrays.stream(ARRAY_DATA); StreamSupport.stream(ITERABLE_DATA.spliterator(), false); StreamSupport.stream( Spliterators.spliteratorUnknownSize(ITERATOR_DATA, Spliterator.ORDERED), false);
  10. Solution - jOOL static final ImmutableList<String> DATA = ImmutableList.of("foo", "bar",

    "baz", "bazinga"); static final String[] ARRAY_DATA = DATA.stream().toArray(String[]::new); static final Iterable<String> ITERABLE_DATA = DATA; static final Iterator<String> ITERATOR_DATA = DATA.iterator(); // don't do this at home or work! How create Stream? Seq.seq(DATA); Seq.seq(ARRAY_DATA); Seq.seq(ITERABLE_DATA); Seq.seq(DATA);
  11. Solution - jOOL (fixed) static final ImmutableList<String> DATA = ImmutableList.of("foo",

    "bar", "baz", "bazinga"); static final String[] ARRAY_DATA = DATA.stream().toArray(String[]::new); static final Iterable<String> ITERABLE_DATA = DATA; static final Iterator<String> ITERATOR_DATA = DATA.iterator(); // don't do this at home or work! How create Stream? Seq.seq(DATA); Seq.of(ARRAY_DATA); Seq.seq(ITERABLE_DATA); Seq.seq(DATA);
  12. We checked exceptions! Arrays.stream(dir.listFiles()).forEach(file -> { try { System.out.println(file.getCanonicalPath()); }

    catch (IOException e) { throw new RuntimeException(e); } // Ouch, my fingers hurt! All this typing! }); ...especially in streams Arrays.stream(dir.listFiles()) .map(Unchecked.function(File::getCanonicalPath)) .forEach(System.out::println);
  13. Libraries On a high level: jOOλ extends/wraps the Java collections.

    Javaslang ships with their own collections. / Lukas Eder, creator of jOOL Which is the best? I suspect, jOOλ is good for quick wins, whereas Javaslang is a strategic decision.
  14. Top tip Remembering CompletableFuture API // CompletableFuture<T> future; public interface

    Function<T, R> { R apply(T t); } future.thenApply(function) // CompletableFuture<R> public interface Consumer<T> { void accept(T t); } future.thenAccept(consumer) // CompletableFuture<Void> + xxxAsync for custom Executor
  15. Date API java.time The main API for dates, times, instants,

    and durations. (...) They are based on the ISO calendar system, which is the de facto world calendar following the proleptic Gregorian rules. All the classes are immutable and thread-safe. “
  16. Dates and parsing String value = "2001-08-22 03:04:05.321 America/Los_Angeles"; LocalDateTime

    localDateTime = LocalDateTime.now(ZoneId.of(value.substring(23, value.length()).trim())) .with(LocalDateTime.parse(value.substring(0, 23).trim(), TIMESTAMP)); System.out.println(localDateTime); // 2001-08-22T03:04:05.321 Custom format
  17. Dates and parsing private static final DateTimeFormatter DATE = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    private static final DateTimeFormatter TIME = DateTimeFormatter.ofPattern("HH:mm:ss.SSS"); private static final DateTimeFormatter TIMESTAMP_WITH_TIME_ZONE = new DateTimeFormatterBuilder() .append(DATE) .appendLiteral(' ') .append(TIME) .appendLiteral(' ') .appendZoneId() .toFormatter(); String value = "2001-08-22 03:04:05.321 America/Los_Angeles"; LocalDateTime localDateTime = LocalDateTime.parse(value, TIMESTAMP_WITH_TIME_ZONE); System.out.println(localDateTime); // 2001-08-22T03:04:05.321 DateTimeFormatterBuilder
  18. Dates and parsing private static final DateTimeFormatter TIMESTAMP_WITH_TIME_ZONE = new

    DateTimeFormatterBuilder() .append(DateTimeFormatter.ISO_LOCAL_DATE) .appendLiteral(' ') .append(DateTimeFormatter.ISO_LOCAL_TIME) .appendLiteral(' ') .appendZoneId() .toFormatter(); String value = "2001-08-22 03:04:05.321 America/Los_Angeles"; LocalDateTime localDateTime = LocalDateTime.parse(value, TIMESTAMP_WITH_TIME_ZONE); System.out.println(localDateTime); // 2001-08-22T03:04:05.321 DateTimeFormatterBuilder
  19. Duration // shiny new Duration class! long durationMillis = 1000L;

    TimeUnit unit = TimeUnit.MILLISECONDS; Duration duration = Duration.of(durationMillis, unit); What’s wrong with these examples? // so let's use proper units Duration duration = Duration.of(2, ChronoUnit.MONTHS); java.time.temporal.UnsupportedTemporalTypeException: Unit must not have an estimated duration
  20. Optional To be, or not to be… (aka avoiding null)

    Sigh, why does everything related to Optional have to take 300 messages? ” Brian Goetz (2013-10-23 on lambda-libs-spec-experts) “ Junior Developer taking advice before starting work on a legacy project http://classicprogrammerpaintings.com/
  21. Optional Problems • OptionalResult Naming is hard... • Optional#getOrElseThrowNoSuchElementException() Naming

    is hard… again. • Implements Serializable? Deliberately not. • If / else on Optional? Vide using .get(). • Optional#stream() Use stream.flatMap(Optional::stream) instead of: stream.filter(Optional::isPresent).map(Optional::get)
  22. Optional Rules 1. Never, ever, use null for an Optional

    variable or return value. 2. Never use Optional.get() unless you can prove that the Optional is present. 3. Prefer alternatives APIs over Optional.isPresent() and Optional.get(). 4. It’s generally a bad idea to create an Optional for the specific purpose of chaining methods from it to get a value. 5. If an Optional chain has a nested Optional chain, or has an intermediate result of Optional<Optional<T>>, it’s probably too complex. 6. Avoid using Optional in fields, method parameters, and collections. 7. Don’t use an Optional to wrap any collection type (List, Set, Map). Instead, use an empty collection to represent the absence of values.