Java8 - Intermediate and terminal operations

Category : Java | Sub Category : Java8 Features | By Prasad Bonam Last updated: 2023-11-13 04:41:44 Viewed : 143

In the Java Stream API, operations can be classified into two main categories: intermediate operations and terminal operations.

Intermediate Operations:

Intermediate operations transform a stream into another stream. They are lazy, meaning they dont execute until a terminal operation is invoked. Intermediate operations allow you to create a pipeline of operations to be performed on the elements of a stream. Here are some common intermediate operations:

  1. filter(Predicate<T> predicate):

    • Filters the elements of the stream based on a given predicate.
    List<String> myList = Arrays.asList("a1", "a2", "b1", "c2", "c1"); List<String> result = .filter(s -> s.startsWith("c")) .collect(Collectors.toList()); // Result: [c2, c1]
  2. map(Function<T, R> mapper):

    • Transforms each element of the stream using the provided function.
    List<String> result = .map(String::toUpperCase) .collect(Collectors.toList()); // Result: [A1, A2, B1, C2, C1]
  3. flatMap(Function<T, Stream<R>> mapper):

    • Flattens the elements of nested streams into a single stream.
    List<List<String>> nestedList = Arrays.asList( Arrays.asList("a1", "a2"), Arrays.asList("b1", "c2", "c1") ); List<String> result = .flatMap(List::stream) .collect(Collectors.toList()); // Result: [a1, a2, b1, c2, c1]
  4. distinct():

    • Removes duplicate elements from the stream.
    List<String> result = .distinct() .collect(Collectors.toList()); // Result: [a1, a2, b1, c2, c1]
  5. sorted() and sorted(Comparator<T> comparator):

    • Sorts the elements of the stream in their natural order or based on a comparator.
    List<String> result = .sorted() .collect(Collectors.toList()); // Result: [a1, a2, b1, c1, c2]

Terminal Operations:

Terminal operations produce a result or a side effect. After a terminal operation is invoked, the stream is consumed, and it cannot be reused. Here are some common terminal operations:

  1. forEach(Consumer<T> action):

    • Applies the given action to each element of the stream.
    java .forEach(System.out::println); // Prints each element of the stream
  2. collect(Collector<T, A, R> collector):

    • Performs a mutable reduction on the elements of the stream using a Collector.
    List<String> result = .filter(s -> s.startsWith("c")) .collect(Collectors.toList()); // Result: [c2, c1]
  3. reduce(T identity, BinaryOperator<T> accumulator) and reduce(BinaryOperator<T> accumulator):

    • Performs a reduction on the elements of the stream using an associative accumulation function.
    Optional<String> concatenated = .reduce((s1, s2) -> s1 + s2); // Result: Optional[a1a2b1c2c1]
  4. count():

    • Returns the count of elements in the stream as a long.
    long count = .count(); // Result: 5
  5. anyMatch(Predicate<T> predicate), allMatch(Predicate<T> predicate), and noneMatch(Predicate<T> predicate):

    • Check if any, all, or no elements of the stream match a given predicate.
    boolean anyStartsWithA = -> s.startsWith("a")); // Result: true boolean allStartWithA = -> s.startsWith("a")); // Result: false boolean noneStartsWithZ = -> s.startsWith("z")); // Result: true
  6. findFirst() and findAny():

    • Returns the first or any element of the stream, wrapped in an Optional.
    Optional<String> firstElement =; // Result: Optional[a1]

These are some common intermediate and terminal operations in the Stream API. Combining these operations allows developers to write expressive and concise code for data processing.

Related Articles

Leave a Comment: