Lambda expressions and Stream API with Groovy or JAVA8

Posted by 행동하지 않으면 성공도 실패도 없다!! Just Do It!! on Friday, November 11, 2016

Lambda expressions and Stream API with Groovy and JAVA 8

Iteration

  • groovy
def numbers = [1, 2, 3, 4, 5, 6]
numbers.each { e -> println e }
numbers.each { println it }
  • java
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
numbers.forEach(e -> System.out.println(e));
numbers.forEach(System.out::println);

collect

  • groovy
def numbers = [1, 2, 3, 4, 5, 6]
numbers.collect { it * 2 }.each { e -> println e }
println numbers.collect { it * 2 }
  • java 8
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
numbers.stream()
 .map(e -> e * 2)
 .forEach(System.out::println);

System.out.println(
  numbers.stream()
   .map(e -> e * 2)
   .collect(Collectors.toList()));

find

  • groovy
def numbers = [1, 2, 3, 4, 5, 6]
println numbers.find { it % 2 == 0}
  • java 8
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);

System.out.println(
    numbers.stream()
           .filter(e -> e % 2 == 0)
           .findFirst());

System.out.println(
    numbers.stream()
           .filter(e -> e % 2 == 0)
           .findFirst()
           .get());

System.out.println(
    numbers.stream()
           .filter(e -> e % 2 == 0)
           .findFirst()
           .orElse(0));

findAll

  • groovy
def numbers = [1, 2, 3, 4, 5, 6]
println numbers.findAll { it % 2 == 0}
  • java 8
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
System.out.println(
  numbers.stream()
             .filter(e -> e % 2 == 0)
             .collect(Collectors.toList()));

inject

  • groovy
def numbers = [1, 2, 3, 4, 5, 6]
println numbers.collect { it * 2 }.inject(0) { c, e -> c + e }
  • java 8
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);

System.out.println(
  numbers.stream()
             .map(e -> e * 2)
             .reduce(0, (c, e) -> c + e));

System.out.println(
  numbers.stream()
             .map(e -> e * 2)
             .reduce(0, Math::addExact));

join

  • groovy
def names = [‘Jack’, ‘Sara’, ‘Jill’]
println names.collect {it.toUpperCase() }.join(‘, ‘)
  • java 8
List<String> names = Arrays.asList(Jack, Sara, Jill);

System.out.println(
  names.stream()
           .map(String::toUpperCase)
           .collect(joining(, )));

lazy evalution

  • java 8
public class Sample {
  public static boolean isGT3(int number) {
    System.out.println(isGT3  + number);
    return number > 3;
  }

  public static boolean isEven(int number) {
    System.out.println(isEven  + number);
    return number % 2 == 0;
  }

  public static int doubleIt(int number) {
    System.out.println(doubleIt  + number);
    return number * 2;
  }

  public static void main(String[] args) {
    List<Integer> numbers = Arrays.asList(1, 2, 3, 5, 4, 6, 7, 8, 9, 10);
    int result = numbers.stream()
                        .filter(Sample::isGT3)
                        .filter(Sample::isEven)
                        .map(Sample::doubleIt)
                        .findFirst()
                        .get();

    System.out.println(Result:  + result);
    System.out.println(Lets see the effect of laziness);
    numbers.stream()
           .filter(Sample::isGT3)
           .filter(Sample::isEven)
           .map(Sample::doubleIt);

    System.out.println(No work expended);

  }
}

infinite series

  • java 8
import java.util.*;
import java.util.stream.Stream;
import static java.util.stream.Collectors.toList;

public class Sample {
  public static List<Integer> seriesOfDouble(int size) {
      return Stream.iterate(1, e -> e * 2)
                   .limit(size)
                   .collect(toList());
  }

  public static void main(String[] args) {
      System.out.println(seriesOfDouble(5));
      System.out.println(seriesOfDouble(10));
  }
}

parallel collections

  • java 8
import java.util.*;
import java.util.stream.Stream;

public class Sample {
  public static int doubleIt(int number) {
        try { Thread.sleep(1000); } catch(Exception ex) {} //assume a computation intensive code here
        return number * 2;
  }

  public static int doubleAndTotal(Stream<Integer> values) {
        long start = System.nanoTime();
        try {
          return values.mapToInt(Sample::doubleIt)
                       .sum();
        } finally {
          long end = System.nanoTime();
          System.out.println(Time taken (s):  + (end  start) / 1.0e9);
        }
  }

  public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        System.out.println(doubleAndTotal(numbers.stream()));
        System.out.println(doubleAndTotal(numbers.parallelStream()));
  }
}

invoke dynamic

  • java 8
import java.util.*;

public class UsingLambdas {
  public static void main(String[] args) {
        List<Integer> values = Arrays.asList(1, 2, 3);
        values.forEach(e -> System.out.println(e));
        values.forEach(e -> System.out.println(e));
        values.forEach(e -> System.out.println(e));
        values.forEach(e -> System.out.println(e));
        values.forEach(e -> System.out.println(e));
  }
}

//javac UsingLambdas
//ls (or dir)
//See the lack of inner classes.
//Do javap -c UsingLambdas
//examine the bytecode and look for invokedynamic
//now remove the .class files before procedding to the other example

new (Groovy)

  • groovy
boolean isGT3(int number) {
  println isGT3 $number
  number > 3
}

boolean isEven(int number) {
  println isEven $number
  number % 2 == 0
}

int doubleIt(int number) {
  println doubleIt $number
  number * 2
}

def numbers = [1, 2, 3, 5, 4, 6, 7, 8, 9, 10]
//traditional Groovy functional style is eager.
def eagerResult = numbers.findAll { isGT3(it) }.findAll { isEven(it) }.collect { doubleIt(it) }.find { it }
println Eager Result: $eagerResult
//We can use Java 8 Streams and be lazy – meaning efficient
def result = numbers.stream()
                        .filter { isGT3(it) }
                        .filter { isEven(it) }
                        .map { doubleIt(it) }
                        .findFirst()
                        .get()
println Result: $result
println Lets see the effect of laziness
numbers.stream()
           .filter { isGT3(it) }
           .filter { isEven(it) }
           .map { doubleIt(it) }
println No work expended