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

Java 8 Functional Programming for Groovy Developers

Java 8 Functional Programming for Groovy Developers

An introduction to the JDK8 functional model for Groovy developers.

John Engelman

July 31, 2015
Tweet

More Decks by John Engelman

Other Decks in Technology

Transcript

  1. JDK 8 Functional
    Programming
    …For Groovy Developers

    View Slide

  2. John Engelman
    • @johnrengelman
    • github.com/johnrengelman
    • ratpack.io
    • objectpartners.com/category/blog

    View Slide

  3. Caveats
    • Scala
    • Clojure
    • Erlang
    • Haskell

    View Slide

  4. …Big pile of Salt

    View Slide

  5. View Slide

  6. Questions?

    View Slide

  7. public static TransformablePublisher stream(Publisher publisher) {
    return Streams.transformable(subscriber -> require().streamSubscribe((handle) ->
    publisher.subscribe(new Subscriber() {
    @Override
    public void onSubscribe(final Subscription subscription) {
    handle.event(() ->
    subscriber.onSubscribe(subscription)
    );
    }
    @Override
    public void onNext(final T element) {
    handle.event(() -> subscriber.onNext(element));
    }
    @Override
    public void onComplete() {
    handle.complete(subscriber::onComplete);
    }
    @Override
    public void onError(final Throwable cause) {
    handle.complete(() -> subscriber.onError(cause));
    }
    })
    ));
    }

    View Slide

  8. java.util.function
    https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html

    View Slide

  9. JDK8 Functional Interfaces
    Conceptually, a functional interface has exactly
    one abstract method.
    - https://docs.oracle.com/javase/8/docs/api/java/
    lang/FunctionalInterface.html

    View Slide

  10. public interface Supplier {
    T get();
    }

    View Slide

  11. Supplier supply() {
    return (() -> {
    return new Foo();
    });
    }
    lambda expression
    parameters list
    body

    View Slide

  12. Supplier supply() {
    return (() -> new Foo());
    }
    implicit return
    where have we seen
    that before?

    View Slide

  13. Supplier supply() {
    return Foo::new
    }
    method handle

    View Slide

  14. Supplier supply() {
    return {
    new Foo()
    }
    }
    Supplier supply() {
    //http://mrhaki.blogspot.com/2015/03/groovy-goodness-
    use-constructor-as.htm
    Foo.metaClass.&invokeConstructor
    }

    View Slide

  15. public interface Consumer {
    void accept(T t);
    }

    View Slide

  16. Consumer consume() {
    return (val -> System.out.println(val));
    }
    Consumer consumeMethod() {
    return System.out::println;
    }

    View Slide

  17. Consumer consume() {
    return { val ->
    println val.name
    }
    }
    Consumer consumeMethod() {
    this.&println
    }

    View Slide

  18. public interface Function {
    R appy(T t);
    }

    View Slide

  19. Function convert() {
    return (foo -> {
    return new Bar(foo.name);
    });
    }
    Function convertMethod() {
    return Bar::new;
    }

    View Slide

  20. Function convert() {
    return { foo ->
    new Bar(foo.name)
    }
    }
    Function convertMethod() {
    Bar.metaClass.&invokeConstructor
    }

    View Slide

  21. public interface BiConsumer {
    void accept(T t, U u);
    }
    public interface BiFunction {
    R apply(T t, U u);
    }

    View Slide

  22. Where is TriFunction?

    View Slide

  23. • BiConsumer
    • BiFunction
    • BinaryOperator
    • BiPredicate
    • BooleanSupplier
    • Consumer
    • DoubleBinaryOperator
    • DoubleConsumer
    • DoubleFunction
    • DoublePredicate
    • DoubleSupplier
    • DoubleToIntFunction
    • DoubleToLongFunction
    • DoubleUnaryOperator
    • Function
    • IntBinaryOperator
    • IntConsumer
    • IntFunction
    • IntPredicate
    • IntSupplier
    • IntToDoubleFunction
    • IntToLongFunction
    • IntUnaryOperator
    • LongBinaryOperator
    • LongConsumer
    • LongFunction
    • LongPredicate
    • LongSupplier
    • LongToDoubleFunction
    • LongToIntFunction
    • LongUnaryOperator
    • ObjDoubleConsumer
    • ObjIntConsumer
    • ObjLongConsumer
    • Predicate
    • Supplier
    • ToDoubleBiFunction
    • ToDoubleFunction
    • ToIntBitFunction
    • ToIntFunction
    • ToLongBiFunction
    • ToLongFunction
    • UnaryOperator
    Java
    • Closure
    Groovy

    View Slide

  24. java.util.stream
    https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html

    View Slide

  25. List filter(List foos) {
    return foos.stream()
    .filter(foo ->
    foo.name.equals(“bar")
    ).collect(Collectors.toList());
    }
    List map(List foos) {
    return foos.stream()
    .map(Bar::new).collect(Collectors.toList());
    }
    List distinct(List foos) {
    return foos.stream().distinct().collect(Collectors.toList());
    }

    View Slide

  26. List filter(List foos) {
    foos.findAll { foo -> foo.name == 'bar' }
    }
    List map(List foos) {
    foos.collect { new Bar(foo) }
    }
    List distinct(List foos) {
    foos.unique()
    }

    View Slide

  27. public static TransformablePublisher stream(Publisher publisher) {
    return Streams.transformable(subscriber -> require().streamSubscribe((handle) ->
    publisher.subscribe(new Subscriber() {
    @Override
    public void onSubscribe(final Subscription subscription) {
    handle.event(() ->
    subscriber.onSubscribe(subscription)
    );
    }
    @Override
    public void onNext(final T element) {
    handle.event(() -> subscriber.onNext(element));
    }
    @Override
    public void onComplete() {
    handle.complete(subscriber::onComplete);
    }
    @Override
    public void onError(final Throwable cause) {
    handle.complete(() -> subscriber.onError(cause));
    }
    })
    ));
    }

    View Slide

  28. public static TransformablePublisher stream(Publisher publisher) {
    return Streams.transformable { subscriber ->
    require().streamSubscribe { handle ->
    publisher.subscribe(new Subscriber() {
    @Override
    public void onSubscribe(final Subscription subscription) {
    handle.event {
    subscriber.onSubscribe(subscription)
    }
    }
    @Override
    public void onNext(final T element) {
    handle.event { subscriber.onNext(element) }
    }
    @Override
    public void onComplete() {
    handle.complete(subscriber.&onComplete)
    }
    @Override
    public void onError(final Throwable cause) {
    handle.complete { subscriber.onError(cause) }
    }
    })
    }
    }
    }

    View Slide

  29. Default Interface Methods
    • Game changer
    public interface Baz {
    String getName();
    default Bar bar() {
    return new Bar(this);
    }
    }
    Bar interfaceMethod(Baz baz) {
    return baz.bar();
    }
    Bar useInterface() {
    return interfaceMethod(() -> "John");
    }
    becomes a Supplier
    lambda implicitly coerced to
    interface

    View Slide

  30. Default Interface Methods
    • Not directly* supported in Groovy
    * Groovy 2.3 introduced Traits which are similar

    View Slide

  31. References/More Info
    • https://github.com/danveloper/uberconf2014-
    from-groovy-to-java8/blob/master/from-groovy-to-
    java8.pdf
    • Anything w/ Venkat
    • https://www.youtube.com/watch?
    v=Ee5t_EGjv0A

    View Slide