PROGRAMMING

m9/ JAVA
REMEMBERS




Last update:   28-09-2021

Streams API

! With Java 8 Streams we can make bulk operations (sequentiallly or paralel). The source for streams can be arrays, files, regex, etc.
 
import java.util.Arrays;
import java.util.List;

public class App {
    public static void main(String[] args) {
        
        List<String> myList = Arrays.asList("aa", "ba", "bc");
        myList
            .stream()
            .filter(s -> s.startsWith("b"))
            .map(String::toUpperCase)
            .sorted()
            .forEach(System.out::println);  // BA BC
    }
}
... 7 lines
 
We don't have to create a collection in order to work with streams.
 
import java.util.stream.Stream;

public class App {
    public static void main(String[] args) {
        
        Stream.of("aa", "ba", "bc")
            .filter(s -> s.startsWith("b"))
            .map(String::toUpperCase)
            .sorted()
            .forEach(System.out::println); // BA BC
    }
}
... 4 lines
 
Primitive streams use lambdas expression and support aggregate operations.
 
import java.util.Arrays;

public class App {
    public static void main(String[] args) {
        
        Arrays.stream(new int[] {1, 2, 3})
            .map(n -> n * 2)
            .average()
            .ifPresent(System.out::println); // 4.0
        
    }
}
... 3 lines
 

Declarative Programming

! Using declarative approach we can create code that is reusable and testable. The code is more self-explanatory.
 
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * The Problem: Given a list of integers, 
 * find the square of all the even numbers
 * and return them in a new list
 */

public class Declarative {
    
    public static void main(String[] args) {

        List<Integer> mylist = Arrays.asList(
            1, 2, 3, 4, 5, 6, 7, 8, 9, 10
        );


        /**
         * Imperative programming style
         */
        List<Integer> mySquareList = new ArrayList<>();
        for(Integer n : mylist) {
            if (n % 2 == 0) {
                mySquareList.add(n * n);
            }
        }
        System.out.println(mySquareList); // [4, 16, 36, 64, 100]


        /**
         * Declarative programming (streams without lambdas)
         * 
         * Might look more confusing, but it cleary stating
         * what operation each part of the stream is doing
         */
        mySquareList = mylist.stream()
            .filter(
                new Predicate<Integer>() {
                    @Override public boolean test(Integer n) {
                        return n % 2 == 0;
                    }
                })
            .map(
                new Function<Integer, Integer>() {
                    @Override public Integer apply(Integer n) {
                        return n * n;
                    }
                }
            )
            .collect(Collectors.toList());
        System.out.println(mySquareList); // [4, 16, 36, 64, 100]


        /**
         * Declarative programming (lambdas)
         * 
         * Simple and reusable
         */
        mySquareList = mylist.stream()
            .filter(x -> x % 2 == 0)
            .map(y -> y * y)
            .collect(Collectors.toList());
        System.out.println(mySquareList); // [4, 16, 36, 64, 100]
    }
}
... 54 lines
 

STREAM FUNCTIONS

! Streams are collection of objects on which you can apply various methods while they are in the pipeline of execution. Lambdas are language constructs that remove the need of writing anonymous functions.
 
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class Declarative {
    
    public static void main(String[] args) {

        /**
         * Filter:
         * 
         * Only elements that meet the condition ...
         * will be passed to the next function in the pipeline
         */
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        numbers.stream()
            .filter(x -> x % 2 == 0)
            .forEach(System.out::println); // 2 4
            
        /** 
         * Map:
         * 
         * Used to transform an element into other element
         */
        List<String> letters = Arrays.asList("a", "b", "c");
        letters.stream()
            .map(x -> x.toUpperCase())
            .forEach(System.out::println); // A B C

        /**
         * ForEach:
         * 
         * Runs for every element in the stream
         */
        List<Integer> myNumbers = Arrays.asList(1, 2, 3, 4, 5);
        myNumbers.stream()
            .filter(x -> x % 2 == 0)
            .map(x -> x * x)
            .forEach(System.out::println); // 4 16

        /**
         * Collect:
         * 
         * Collects every element in the stream to another collection
         */
        List<String> myList = Arrays.asList("London", "Paris", "London");
        Set<String> mySet = myList.stream()
            .filter(x -> x.length() % 2 == 0)
            .collect(Collectors.toSet()); // no duplicates (Set)
        System.out.println(mySet); // [London]
        
    }
}
... 41 lines
 

Questions     github Collections
Json

        A B C D E F
🔔
1/3