Java Streams - ashwin-shetty/Documents-Wiki GitHub Wiki

Java Stream
Stream API is used to process collections of objects. A stream can have multiple intermediate operation and one terminal operation.

 Arrays.asList(4,6,8,10).stream().forEach(integer -> System.out.print(integer+ " "));
 List<Integer> numbers = Arrays.asList(4,6,8,30,13,3,3,5,3,8,5);

Reduce() allows to produce one single result from a sequence of elements. It contains two part Identity initial value of the reduction operation and also the default result if the stream is empty. Accumulator a function that takes two parameters, a partial result of the reduce operator and the next element of the stream.

  Integer sum = numbers.stream().reduce(0, (subTotal, number) -> subTotal + number);
  //Result : 88

In this example 0 is the Identity and lambda expression is Accumlator.

Filter() is an intermediate operation of the stream interface that allows to filter elements with boolean output

  List<Integer> oddNumberList = numbers.stream().filter(number -> number % 2 == 1)
                                       .collect(Collectors.toList());
  //Result : [13, 3, 3, 5, 3, 5]

In this example if number % 2 is true then those numbers are filtered and using terminal operation collect, it is stored in List.

Map() is an intermediate operation of the stream interface that return list of value

  List<Integer> modResultList = numbers.stream().map(number -> number % 2)
                                       .collect(Collectors.toList());
  //Result : [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1]

Method Reference

// Method deletes all all the map values whose id's are present in set
public void deleteMap(Map<Integer, String> mainMap, Set<Integer> deleteSet) { ;
  // Java 6 style
  for(Integer id : deleteSet) {
    mainMap.remove(id);
  }
  
  // Stream Remove Values
  deleteSet.forEach(id -> mainMap.remove(id));

  // Stream with Method Reference
  deleteSet.forEach(mainMap::remove);
  
}

Others

public class Main {

    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(4,6,8,30,13,3,3,5,3,8,5);

        Predicate<Integer> oddPredicate = createEvenPredicate();

        // Stream can have mulitple intermediate operation and one terminal operation

        // Stream Basic
        {
            numbers.stream().forEach(integer -> System.out.print(integer+ " "));
        }

        // Using Reduce
        {
            System.out.println("");
            Integer sum = numbers.stream().reduce(0, (number1, number2) -> number1 + number2);
            System.out.println("Sum of all numbers " + sum);
        }

        // Using filter
        {
            Integer oddSum = numbers.stream()
                    .filter(number -> number % 2 == 1)
                    .reduce(0, (number1, number2) ->  number1 + number2);
            System.out.println("Sum of odd  numbers " + oddSum);
        }


        // Stream Sort
        {
            System.out.print("Sorted List ::");
            numbers.stream().sorted().forEach(integer -> System.out.print(integer +" "));
            System.out.println("");
        }

        // Stream distinct
        {
            System.out.print("Distinct List ::");
            numbers.stream().distinct().forEach(integer -> System.out.print(integer +" "));
            System.out.println("");
        }

        // Stream Map
        {
            System.out.print("Map List ::");
            numbers.stream().map(e -> e *e).forEach(integer -> System.out.print(integer +" "));
            System.out.println("");
        }


        // IntStream  and Map, upper bound is exclusive means 10 will not be used only from 1 to 9
        {
            IntStream.range(1, 10).map(e -> e * e).forEach(p -> System.out.print(p + " "));
            System.out.println("");
        }

        // IntStream  and Sum of the range
        {
          int sum =  IntStream.range(1, 10).map(new CustomIntUnaryOperator()).reduce(0, (n1,n2) -> n1+n2);
            System.out.println("Sum is " + sum);
        }


        // Stream List to lowercase
        {
            Arrays.asList("Apple", "Orange", "Banana").stream().map(s -> s.toLowerCase()).forEach(new SystemOutConsumer());
            System.out.println("");
        }

        // Stream compare min and max (n1,n2) -> Integer.compare(n1,n2)
        {
           int num = numbers.stream().max((n1,n2) -> Integer.compare(n1,n2)).get();
            System.out.println("Larger number is " + num);
        }


        // Using method reference
        {
            int num = numbers.stream().max(Integer :: compare).get();
            System.out.println("Larger number is " + num);
        }

        // Stream compare using using comparingInt and orElse for default value
        {
            int num = numbers.stream().min(Comparator.comparingInt(n -> n)).orElse(-1);
            System.out.println("Smallest number is " + num);
        }

        {
            List<Integer> num = numbers.stream().filter(e -> e%2 == 1).collect(Collectors.toList());
            System.out.println("Odd number are "+ num);
        }

        // Method Reference is a way in which we refer method instead of calling system.out.println we use System.out :: print
        // Method reference can used for static and instance method  eg: String :: length
        {
            System.out.println("Method Reference");
            IntStream.range(1, 10).map(e -> e * e).forEach(System.out :: print);
            System.out.println("");
        }


        // Lambda Expression (number1, number2) -> number1 + number2
        // In functional implementation there will be one method which doesnt have implementation which will be replaced by lambda
    }

    private static Predicate<Integer> createEvenPredicate() {
        return e -> e % 2 == 1;
    }

    // without Reduce
    private static int normalSum(List<Integer> numbers) {
        int sum =0;
        for (int number : numbers) {
            sum += sum;
        }
        return sum;
    }

    //Consumer<? super T> action
    //void accept(T t);


}

class SystemOutConsumer implements Consumer<String> {

    @Override
    public void accept(String name) {
        System.out.println(name);
    }
}

class CustomIntUnaryOperator implements IntUnaryOperator {

    @Override
    public int applyAsInt(int operand) {
        return operand*operand;
    }
}

class CustomFunction implements Function<String,String> {

    @Override
    public String apply(String s) {
        return s.toLowerCase()+s.toUpperCase();
    }
}
⚠️ **GitHub.com Fallback** ⚠️