Java. The Stream interface. Intermediate interface methods




The Stream<T> interface. Intermediate interface methods. Examples of using. Methods filter(), map(), mapToDouble(), mapToInt(), mapToLong(), sorted()


Contents


Search other websites:

1. The concept of an intermediate operation. Stateless and stateful intermediate operations

An intermediate operation means a method (function) that creates a new data stream based on the original (calling) data stream. The creation of a new data stream can occur in several stages in pipeline mode.

Intermediate operations are characterized by:

  • performing a stateless operation. In this case, each element is processed independently of the others elements. For example, in the filter() method, fetching an element into a new stream does not depend on the values of other elements in the original stream;
  • performing a stateful operation. In this case, the processing of an item depends on the characteristics of other items. An example of this is sorting elements, where the position of an element depends on the values of other elements (sorted() method).

When performing intermediate operations, the save (non-save) state is important in the case of parallel processing of data streams. This is because stateful operations can be performed in multiple passes. At the same time, stateless operations can be performed in one pass.

 

2. Method filter(). Get a new stream according to the condition (predicate). Example

The filter() method is designed to get a new stream according to the specified condition. The method has the following general form

Stream<T> filter(Predicate<? super T> predicate)

here

  • T – the type of stream elements;
  • Stream<T> – the resulting filtered stream;
  • Predicate<? super T> – predicate that specifies the filtering condition.

The filter() method is an intermediate operation.

Example. The example uses the filter() method to create a new stream of Double type. In the new stream, numbers are formed that are greater than 2.5.

import java.util.*;
import java.util.stream.*;
import java.util.function.*;

public class StreamAPI {

  public static void main(String[] args) {
    // The filter() method - get a new stream according to the predicate
    // 1. Create a set of numbers
    ArrayList<Double> AL = new ArrayList<Double>();
    AL.add(1.5);
    AL.add(2.8);
    AL.add(-2.3);
    AL.add(3.4);
    AL.add(1.1);

    // 2. Get a data stream
    Stream<Double> stream = AL.stream();

    // 3. Create predicate for filter() method
    Predicate<Double> predicate;

    // 4. Specify lambda expression for predicate
    //    The selection condition is specified in the lambda expression: the number is greater than 2.5
    predicate = (n) -> n>2.5;

    // 5. Get a new stream
    Stream<Double> streamFiltered = stream.filter(predicate);

    // 6. Display the new stream using iterator
    Iterator<Double> it = streamFiltered.iterator();
    System.out.println("Filtered stream: ");
    while (it.hasNext())
      System.out.print(it.next()+" ");
  }
}

Program execution result

Filtered stream:
2.8 3.4

 

3. Method map(). Apply the specified display function to the elements of the calling thread. Example

The map() method is used to apply some mapping function to a stream. Method returns the resulting stream. The method has the following general form:

R Stream<R> map(Function<? super T, ? extends R> mapper)

here

  • R – type of elements of the resulting stream;
  • T – type of source stream elements;
  • mapper – lambda expression that performs an action on elements of the original stream;
  • Function<? super T, ? extends R> – a type corresponding to the Java standard functional interface. This interface defines the apply() method, which performs some function on stream elements.

The method is an intermediate operation.

Example. The example demonstrates the use of the map() method for the following tasks:

  • for a given stream of strings, generate a new stream of integers. Each number in the resulting stream is the length of the corresponding string in the original stream;
  • for a given stream of lines, form a new stream of lines. Each line of the resulting stream is reversed to the corresponding line of the original stream.

 

import java.util.*;
import java.util.stream.*;
import java.util.function.*;

public class StreamAPI {

  public static void main(String[] args) {
    // Method map() - apply a mapping function to stream elements
    // 1. Create a set of strings
    ArrayList<String> AL = new ArrayList<String>();
    AL.add("dictionary");
    AL.add("month");
    AL.add("face");
    AL.add("table");
    AL.add("object");
    AL.add("string");

    // 2. Get the stream
    Stream<String> stream = AL.stream();

    // 3. Declare a reference to the functional interface Function<T, R>
    Function<String, Integer> mapper;

    // 4. Form a new stream, in which each element is the length
    //    of the corresponding line of the original stream,
    //   for example, dictionary-> 10, month-> 5, face-> 4, ...
    // 4.1. Declare the appropriate lambda expression
    mapper = (str) -> {
      return str.length();
    };

    // 4.2. Create a new stream
    Stream<Integer> streamInt = stream.map(mapper);

    // 4.3. Display a new stream using iterator
    Iterator<Integer> iterator = streamInt.iterator();
    System.out.print("streamInt = [ ");
    while (iterator.hasNext()) {
      System.out.print(iterator.next() + " ");
    }
    System.out.println("]");

    // ---------------------------------------------------------------
    // 5. Create a new stream of strings
    //   in which strings are displayed in reverse order
    // 5.1. Declare a display function and assign a lambda expression to it
    Function<String, String> mapperStr = (str) -> {
      String str2 = "";
      for (int i=0; i<str.length(); i++)
        str2 = str2 + str.charAt(str.length() - i - 1);
      return str2;
    };

    // 5.2. Create a new stream of reversed strings
    Stream<String> streamReverseStr = AL.stream().map(mapperStr);

    // 5.3. Display a new stream using the forEach() method
    Consumer<String> action = (n) -> {
      System.out.print(n + " ");
    };
    System.out.print("streamReverseStr = [ ");
    streamReverseStr.forEach(action);
    System.out.println("]");
  }
}

Program execution result

streamInt = [ 10 5 4 5 6 6 ]
streamReverseStr = [ yranoitcid htnom ecaf elbat tcejbo gnirts ]

 

4. Method mapToDouble(). Apply a mapping function to a data stream of type DoubleStream

The mapToDouble() method is designed to apply a mapping function to a data stream of Double type. The general form of the method is as follows:

DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper)

here

  • T – the elements type of the original data stream;
  • DoubleStream – a sequence of elements of primitive type double, which is a specialization of Stream;
  • ToDoubleFunction<? super T> – a functional interface containing the applyAsDouble() method. The method receives data of the generic type T and returns a result of type double. It is a specialization of the functional interface Function that returns a double type.

The mapToDouble() method is an intermediate operation.

Example. The example uses the mapToDouble() method to get a Double data stream from an Integer data stream. A square root operation is performed on each element of the input data stream of type Integer.

import java.util.*;
import java.util.stream.*;
import java.util.function.*;

public class StreamAPI {

  public static void main(String[] args) {
    // Method MapToDouble() - get a data stream of Double type based on the mapping function
    // 1. Create a set of Integer numbers
    ArrayList<Integer> AL = new ArrayList<Integer>();
    AL.add(25);
    AL.add(36);
    AL.add(144);
    AL.add(256);
    AL.add(225);
    AL.add(81);

    // 2. Get an Integer data stream from the AL set
    Stream<Integer> stream = AL.stream();

    // 3. Implement a mapping function for data of type Integer.
    //   We need to get the square root of each element of the stream.
    ToDoubleFunction<Integer> mapper;

    // Lambda expression that returns the square root of an integer
    mapper = (value) -> Math.sqrt(value);

    // 4. Call the mapToDouble() method - get a new stream
    DoubleStream streamDouble = stream.mapToDouble(mapper);

    // 5. Display a new stream using iterator
    Iterator<Double> it = streamDouble.iterator();
    System.out.print("streamDouble = [ ");
    while (it.hasNext())
      System.out.print(it.next() + " ");
    System.out.println("]");
  }
}

Program execution result

streamDouble = [ 5.0 6.0 12.0 16.0 15.0   9.0 ]

 

5. Method mapToInt(). Apply a mapping function to a data stream of type IntStream. Example

The mapToInt() method is designed to apply a mapping function to an Integer data stream. The general form of the method is as follows

IntStream mapToInt(ToIntFunction<? super T> mapper)

here

  • IntStream – a sequence of int values, which is a primitive int implementation of the Stream type;
  • ToIntFunction<? super T> – the type of a mapping function that converts data from generic type T to data of type int. This is a specialization of the standard Function interface for int type;
  • mapper – a mapping function that is applied to a data stream of generic type T.

Example. The example converts an original Double stream to a resulting Integer stream. Each element of the original stream is rounded to the nearest integer.

import java.util.*;
import java.util.stream.*;
import java.util.function.*;

public class StreamAPI {

  public static void main(String[] args) {
    // Method MapToInt() - get an int data stream based on the mapping function
    // 1. Create a set of numbers of type Double
    ArrayList<Double> AL = new ArrayList<Double>();
    AL.add(25.7);
    AL.add(36.88);
    AL.add(144.05);
    AL.add(256.2);
    AL.add(225.7);
    AL.add(81.4);

    // 2. Get a data stream of type Double from set AL
    Stream<Double> stream = AL.stream();

    // 3. Implement a mapping function for data of type Integer.
    //    Mapping function
    ToIntFunction<Double> mapper;

    // A lambda expression that returns an Integer result.
    // Each Double element is rounded to the nearest integer
    mapper = (value) -> {
      return (int)(value+0.5);
    };

    // 4. Invoke method mapToInt() - get a new stream
    IntStream streamInt = stream.mapToInt(mapper);

    // 5. Display a new stream using iterator
    Iterator<Integer> it = streamInt.iterator();
    System.out.print("streamInt = [ ");
    while (it.hasNext())
      System.out.print(it.next() + " ");
    System.out.println("]");
  }
}

Program execution result

streamInt = [ 26 37   144 256 226   81 ]

 

6. Method mapToLong(). Apply a mapping function to a LongStream data stream. Example

The mapToLong() method is used when you need to get a stream of data of type Long. The method uses a mapping function for some type T that returns a result of type Long. The general form of the method is as follows:

LongStream mapToLong(ToLongFunction<? super T> mapper)

here

  • mapper – a mapping function that is represented as a lambda expression. The function gets the value of an element of the generic type T and returns the result;
  • ToLongFunction<? super T> – the type of mapping function used to receive data of type Long;
  • LongStream – a type that reflects a sequence of elements of long type.

The mapToLong() method is an intermediate operation.

Example. The example converts the Integer numbers from the source stream to the resulting Long stream. Each stream number is squared.

import java.util.*;
import java.util.stream.*;
import java.util.function.*;

public class StreamAPI {

  public static void main(String[] args) {
    // Method mapToLong() - get a stream of data of type Long based on the mapping function
    // 1. Create a set of numbers of Integer type
    ArrayList<Integer> AL = new ArrayList<Integer>();
    AL.add(25);
    AL.add(3688);
    AL.add(14405);
    AL.add(2562);
    AL.add(2257);
    AL.add(8144);

    // 2. Get an Integer data stream from the AL set
    Stream<Integer> stream = AL.stream();

    // 3. Реализовать функцию отоображения для данных типа Integer
    //   The mapping function returns the squares of the numbers of type Integer
    ToLongFunction<Integer> mapper;

    // A lambda expression that returns a Long result,
    // each Integer is squared
    mapper = (value) -> {
      return (long)value * (long)value;
    };

    // 4. Call the mapToLong() method - get a new stream
    LongStream streamLong = stream.mapToLong(mapper);

    // 5. Output a new stream using an iterator
    Iterator<Long> it = streamLong.iterator();
    System.out.print("streamLong = [ ");
    while (it.hasNext())
      System.out.print(it.next() + " ");
    System.out.println("]");
  }
}

The result of the program

streamLong = [ 625 13601344   207504025 6563844 5094049   66324736 ]

 

7. Method sorted(). Sort items in ascending and descending order. Example

The sorted() method allows you to get a sorted stream from the calling stream. The method has two overloaded implementations.

The general form of the first implementation of the method is as follows:

Stream<T> sorted()

here

  • T – type of stream elements;
  • Stream<T> – the resulting sorted stream. Items are sorted in ascending order (natural order).

The general form of the second implementation of the method is as follows:

Stream<T> sorted(Comparator<? super T> comparator)

here

  • T – the type of stream elements;
  • Stream<T> – the resulting stream sorted in descending order;
  • Comparator<? super T> – a type of Java standard functional interface that contains a method that compares two values;
  • comparator – the method into which the lambda expression code is written. The lambda expression takes two parameters and compares them. The expression returns an integer (<0, ==0, >0) depending on whether the first parameter is less (equal, greater than) than the second parameter.

The sorted() method is the intermediate operation.

Example. The example demonstrates the use of the sorted() method to sort strings:

  • in ascending order of elements (natural order);
  • in descending order of elements.
import java.util.*;
import java.util.stream.*;

public class StreamAPI {

  public static void main(String[] args) {
    // Method sorted() - sort items in natural order (ascending)
    // 1. Create a set of strings
    ArrayList<String> AL = new ArrayList<String>();
    AL.add("dictionary");
    AL.add("month");
    AL.add("face");
    AL.add("table");
    AL.add("object");
    AL.add("string");

    // 2. Sort in natural order
    // 2.1. Get a steram from ArrayList<String>
    Stream<String> stream = AL.stream();

    // 2.2. Invoke method sorted()
    Stream<String> streamSorted = stream.sorted();

    // 2.3. Display the elements of stream streamSorted using iterator
    Iterator<String> iterator = streamSorted.iterator();
    System.out.print("streamSorted = [ ");
    while (iterator.hasNext())
      System.out.print(iterator.next() + " ");
    System.out.println("]");

    // 3. Sort items in descending order
    // 3.1. Declare a comparator - a method that compares two strings
    Comparator<String> comparator;

    // 3.2. Assign a lambda comparison expression to the comparator in reverse order
    comparator = (str1, str2) -> {
      return str2.compareTo(str1);
    };

    // 3.3. Sort strings - the sorted() method with comparator parameter
    Stream<String> streamSortedDesc = AL.stream().sorted(comparator);

    // 3.4. Output strings using iterator
    iterator = streamSortedDesc.iterator();
    System.out.print("streamSortedDesc = [ ");
    while (iterator.hasNext())
      System.out.print(iterator.next()+" ");
    System.out.println("]");
  }
}

The result of the program

streamSorted = [ dictionary face month object string table ]
streamSortedDesc = [ table string object month face dictionary ]

 


Related topics