top of page

What are Streams in Java?



Streams are added to Java APIs to let you manipulate collections of data in a declarative way ( represent in the query instead of writing code).


Problem Statement

Give me all the car names sorted by price and are red in color.


Code without streams

List<Car> filteredCars = new ArrayList<>();
for(Car car : cars) {
    if("red".equals(car.getColor().toLowerCase())) {
        filteredCars.add(car);
    }
}

Collections.sort(filteredCars, new Comparator<Car>() {
    @Override
    public int compare(Car o1, Car o2) {
       return o1.getPrice().compareTo(o2.getPrice());
    }
});

List<String> carNames = new ArrayList<>();
for(Car car : filteredCars) {
    carNames.add(car.getName());
}

Code with streams

List<String> carNames = cars
        .stream()
        .filter(car -> "red".equals(car.getColor().toLowerCase()))
        .sorted(Comparator.comparing(Car::getPrice))
        .map(Car::getName)
        .collect(Collectors.toList());

Operation pipeline



Stream

A sequence of elements from a source that supports data processing.


Components:

  • Source

  • Sequence of elements

  • Data processing operations


Characteristics

  • Pipelining: Most of the stream operations return stream itself allowing to form a larger pipeline.

  • Internal iteration.

List<String> words = Arrays.asList("Streams", "in", "", " ", "Java");
List<String> result = words
        .stream()
        .filter(val -> !val.isBlank())
        .map(String::toUpperCase)
        .limit(2)
        .collect(Collectors.toList());
System.out.println(result);

In the above code, there are few operations

  • Filter: Exclude certain elements from the stream.

  • Map: Transform an element into another.

  • Limit: truncate streams to contain no more than a given number.

  • Collect: Convert a stream into another form.


Stream data processing flow




Stream vs Collection

  • Collection: Collection is an in-memory data structure that holds all the values.

  • Stream: Elements are computed on demand.


Traverse only once

A stream can be traversed only once. Trying to traverse more than one will throw an Illegal state exception.

List<String> words = Arrays.asList("Learning", "Java", "Streams", "");
Stream<String> s = words.stream();

s.forEach(System.out::println);
s.forEach(System.out::println); // will throw exception

External vs Internal Iteration

  • Collection interface requires iteration to be done by the user, this is known as external iteration

  • Stream library does iteration for you, this is internal iteration


Benefits of internal iteration

  • The library has the capability for parallel processing.

  • Optimize the processing algorithm.



Code: External iteration vs Internal Iteration

List<String> words = Arrays.asList("Life", "is", "wonderful");

// External foreach iteration
System.out.print("External iteration (foreach): ");
for(String word: words) {
    System.out.print(word + " ");
}
System.out.println();

// External iterator iteration
Iterator<String> iterator = words.iterator();
System.out.print("External iteration (iterator) : ");
while(iterator.hasNext()) {
    System.out.print(iterator.next() + " ");
}
System.out.println();

// Internal iteration
System.out.println("Internal iteration : ");
List<String> upperCase = words.stream().map(String::toUpperCase).collect(Collectors.toList());


Stream Operations

There are two groups of operations in the stream:

  • Intermediate Operation: They connect together to form a pipeline. Eg. filter, map, limit.

  • Terminal Operation: It causes the pipeline to be executed and close after execution. Eg. collect.


Intermediate operations are lazy. They don’t perform any processing until the terminal operation is invoked on the stream pipeline.



Source: Medium


The Tech Platform

0 comments
bottom of page