Skip to content

Latest commit

 

History

History
423 lines (312 loc) · 8.62 KB

README.md

File metadata and controls

423 lines (312 loc) · 8.62 KB

Java 8 (LTS)

Oracle, OpenJDK1, OpenJDK2


Functional Programming

  • Imperative style programming
    • what to do?
    • How to do?
  • Declarative style programming
    • what to do?
  • Higher order function
    • what is a function?
      • Pass objects to a function
      • Create objects within a function
      • Return objects from a function
    • what is the HOF?
      • Pass functions to a function
      • Create function within a function
      • Return function from a function

Functional programming = Declarative style programming + Higher order function


Lambda Expression

  • Anonymous
    • less to write, and think about
  • Function
    • parameters
    • body
    • return type
    • exceptions
    • ...
  • Passed around
    • passed as argument
    • stored in a variable
  • Concise

Before, After

Behavior Parameterization


Functional Interface

@FunctionalInterface

package: java.util.stream (Interface Stream)

  • Predicate
  • Supplier
  • BiConsumer
  • ...
Functional Interface Function Descriptor Primitive Specialization
Predicate T -> boolean IntPredicate
LongPredicate
DoublePredicate
Consumer T -> void IntConsumer
LongConsumer
DoubleConsumer
Function<T, R> T -> R IntFunction
IntToDoubleFunction
ToDoubleFunction
...
Supplier () -> T BooleanSupplier
IntSupplier
...
UnaryOperator T -> T IntUnaryOperator
LongUnaryOperator
...
BinaryOperator (T, T) -> T IntBinaryOperator
LongBinaryOperator
...
BiPredicate<L, R> (L, R) -> boolean
BiConsumer<T, U> (T, U) -> void ObjIntConsumer
ObjLongConsumer
...
BiFunction<T, U, R> (T, U) -> R ToIntBiFunction<T, U>
ToLongBiFunction<T, U>
...

References: Functional Interface (Oracle), Interface Stream (Oracle)


Method Reference

Before, After

  • Static method (Integer::parseInt)
  • Instance method (of an arbitrary type like String::length)
  • Instance method (of an existing object expensiveTransaction::getValue)

Type 1:

Lambda Method Reference
(args) -> ClassName.staticMethod(args) ClassName.staticMethod

Type 2:

Lambda Method Reference
(arg0, rest) -> arg0.instanceMethod(rest) ClassName::instanceMethod

Type 3:

Lambda Method Reference
(args) -> expr.instanceMethod(args) expr::instanceMethod

Composing Lambda Expressions

  • Comparator
  • Predicate
  • Functions
  • ...

Streams

  • Java API
  • manipulating collections of data in a declarative way
  • query rather than code
  • fancy iterators over data collections
  • parallel transparency, without multithreaded code
  • stateless vs stateful

Filtering

  • filter(Predicate)
    • distinct()
    • limit(int)
    • skip(int)

Mapping

  • map(Function)
  • flatMap()

Finding

  • anyMatch
  • allMatch
  • noneMatch
  • findFirst -> return Optional
  • findAny -> return Optional

Reducing

  • functional programming term "fold"
  • reduce(init value, BinaryOperator< T >)
int sum = numbers.stream().reduce(0, (a, b) -> a + b);
  • reduce(BinaryOperator< T >)
import java.util.Optional;

Optional<Integer> max = numbers.stream().reduce(Integer::max);

Sorting

  • sort(Comparator) => (T, T) -> int

Numeric Streams

  • Hiding boxing cost: mapToInt()
    • int (primitive) -> Integer (Object) : boxing
    • Integer (Object) -> int (primitive) : unboxing
import java.util.stream.IntStream;
import java.util.stream.Stream;

IntStream intStream = Stream.of(1, 2, 3, 4, 5);
Stream<Integer> stream = intStream.boxed();

Collecting data with Streams

  • Grouping
  • Partitioning
  • Multilevel groupings

Parallel Streams

stream.parallel()
      .filter(...)
      .sequential()
      .map(...)
      .parallel()
      .reduce();

Default Methods

  • allows static methods inside interfaces
  • default implementation for methods

Google Guava vs Apache Commons

  • Abstract class vs Interface

Multilevel inheritance

  1. Classes
interface A {
    default void hello() {
        System.out.println("Hello from A");
    }
}

class B implements A {
    public void hello() {
        System.out.println("Hello from B");
    }
}

class C extends B implements A {
    public static void main(String[] args) {
        new C().hello();
    }
}
  1. Specific Sub-Interfaces
interface A {
    default void hello() {
        System.out.println("Hello from A");
    }
}

interface B extends A {
    default void hello() {
        System.out.println("Hello from B");
    }
}

class C implements A, B {
    public static void main(String[] args) {
        new C().hello();
    }
}
  1. Explicitly Select
interface A {
    default int getNum() {
        return 10;
    }
}

interface B {
    default int getNum() {
        return 20;
    }
}

class C implements A, B {
    public static void main(String[] args) {
        System.out.println(new C().getNum()); // compiler error!
    }
}
class C implements A, B {
    public static void main(String[] args) {
        System.out.println(new C().getNum()); // ok!
    }

    public int getNum() {
        return B.super.getNum();
    }
}

Optional

  • Haskell and Scala
  • Cyclomatic complexity
return person.getCar().getInsurance().getDate().getYear();
if(person !=null) {
    Car car = person.getCar();
    if(car !=null){
        Insurance insurance = car.getInsurance();
        if(insurance !=null){
            //...
        }
    }
}
  • Null vs Java philosophy (hiding pointers)

  • Groovy:

def carInsuranceName = person?.car?.insurance?.name

CompletableFuture

  • asynchronous programming
  • non-blocking code
  • separated thread -> notify main thread
  • completion of failure
  • Future vs CompletableFuture
    • Java 5
    • isDone()
    • get()
    • limitations:
      • manual completion
      • callback function
      • chain
      • combine multiple futures
      • exception handling
import java.util.concurrent.CompletableFuture;

CompletableFuture<String> stringCompletableFuture = new CompletableFuture<>();

String result = stringCompletableFuture.get();

New Date Time API

  • Challenges
    • ! thread safe
    • ! internationalize
    • ! reflect UTC
    • millisecond granularity
    • random offsets
    • ...

Backstory

  • James gosling
  • JDK 1
  • JDK 1.1
  • joda-time project

Miscellaneous

  • PermGen
    • PermgenOutOfMemoryException
    • removed
  • Metaspace memory allocation model
    • out of native memory
  • Metaspace capacity
    • MaxMetaspaceSize
  • Foreach
    • list, set, queue, map
import java.util.Arrays;
import java.util.List;

List<String> names = Arrays.asList("Foo", "Bar");
names.forEach(System.out::println);
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

Set<String> uniqueNames = new HashSet<>(Arrays.asList("Foo", "Bar"));
uniqueNames.forEach(System.out::println);
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Queue;

Queue<String> namesQueue = new ArrayDeque<>(Arrays.asList("Foo", "Bar"));
namesQueue.forEach(System.out::println);

Consumer

import java.util.HashMap;
import java.util.Map;

Map<Integer, String> namesMap = new HashMap<>();
namesMap.put(1, "Foo");
namesMap.put(2, "Bar");
namesMap.forEach((key, value) -> System.out.println(key + ": " + value));

BiConsumer