Java Streams

In Java, streams are a way of processing data declaratively. They allow you to specify the operations to be performed on a data source, but not how those operations are performed. This makes it easy to write code that is expressive and easy to read, while still being efficient and scalable.

There are two main types of streams in Java:

  • Sequential streams: These streams process elements one at a time, in a defined order.
  • Parallel streams: These streams process elements concurrently, using multiple threads.

You can create streams from various data sources, such as arrays, collections, and I/O resources. You can then apply a variety of operations to the stream, such as filtering, mapping, and reducing. Finally, you can consume the stream by using a terminal operation, such as forEach() or collect().

Here is an example of how you might use streams to process a list of integers:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Main {
  public static void main(String[] args) {
    List<Integer> numbers = Arrays.asList(5, 2, 7, 1, 3);

    // Filter the list to only include even numbers
    List<Integer> evenNumbers = numbers.stream()
        .filter(n -> n % 2 == 0)
        .collect(Collectors.toList());
    System.out.println(evenNumbers);  // [2]

    // Map the list to a new list of strings
    List<String> strings = numbers.stream()
        .map(n -> "Number: " + n)
        .collect(Collectors.toList());
    System.out.println(strings);  // [Number: 5, Number: 2, Number: 7, Number: 1, Number: 3]

    // Reduce the list to a single value using a sum
    int sum = numbers.stream()
        .reduce(0, (a, b) -> a + b);
    System.out.println(sum);  // 18
  }
}