lang="en-US"> Java Stream API tutorial - Knoldus Blogs
Knoldus Blogs

Java Stream API tutorial

Reading Time: 3 minutes

Java Stream API was one of the major features released with Java 8, that let you code in declarative style.

It supports function-style operations on streams of elements, such as map, filter and various other transformations.

Streams vs Collection

It is a myth that Java Stream API have replaced Collections in Java. Most of the collections are a main source for the stream to work on and they are often used together.

Some of the major difference between Streams and Collection are:


CollectionStream
StorageStorage of data. Collections are about data.No storage of data. Streams are about computations on data
Data ModificationCan add/remove elementsFunctional in nature. Operations on stream eg. filtering will result in a new Stream
IterationExternal iteration on Collections using loops
Perform iteration internally
TraversalCan be traversed multiple timesTraversable only once
EvaluationEager evaluation; All elements are computed in the beginning itselfLazy evaluation; Intermediate operations are not evaluated until terminal operation is invoked.

Creating a Stream

String[] arr = {"d", "b", "c"};
System.out.println("Sorted Stream: " + Stream.of(arr).sorted().collect(Collectors.toList()));

The above code snippet creates a Stream from using Stream.of() and sorts the stream in its natural order, returning a sorted list as output.

Stream Operations

Intermediate operations

Intermediate operations are the ones that return the stream itself. Some of them are:

filter()

It accepts a predicate to filter all elements of the stream. This operation acts as an intermediate by enabling us to call another stream operation on the result.

For example,

knolders.stream().filter((str) -> str.startsWith("K"))
 .forEach(System.out::println);

map()

map lets you convert the given element into another object.

knolders.stream().filter((str) -> str.startsWith("K"))
.map(String::toUpperCase)
.forEach(System.out::println);

Terminal Operations

Terminal operations return a result of a certain type instead of returning a Stream.

forEach()

It helps in iterating over all elements of a stream and perform some operation on the elements.

memberNames.forEach(System.out::println);

collect()

Collect is a useful terminal operation used  to transform the elements of the stream into a different kind of result, e.g. a List, Set or Map.

It accepts a Collector which consists of four different operations: a supplier, an accumulator, a combiner and a finisher.

Java 8 onwards supports various built-in collectors via the Collectors class.

List<String> namesInUppercase = knolders.stream().sorted()
  .map(String::toUpperCase)
 .collect(Collectors.toList());

reduce()

The reduction operation combines all elements of the stream into a single result.

Optional<String> reduced = knolders.stream()
.reduce((s1,s2) -> s1 + "@" + s2);
reduced.ifPresent(System.out::println);

                    

Short circuiting operations

Short-circuiting operations allow the computations on infinite streams to complete in finite time. Some of the short-citcuiting operations are:

limit() 

It limits the stream elements to process.

int [] arr = {1,2,3,4,5,6,7,8,9,11};
Arrays.stream(arr)
      .limit(5)
      .forEach(System.out::println);

findFirst(), findAny()

firstFist() returns the first element from the Stream.
findAny() returns any element from the Stream. It may be possible to get a different result every time with findAny() operation.

int [] arr = {1,2,3,4,5,6,7,8,9};
Integer findFirstElem = Arrays.stream(arr).filter(i -> (i%2) == 0)
.findFirst()
.orElse(-1);

Integer findAnyElem = Arrays.stream(arr).filter(i -> (i%2) == 0)
.findAny()
.orElse(-1);

allMatch(), anyMatch()

These short circuit operators returns true or false value depending on the condition being evaluated.
allMatch() evaluates the condition for all the steams and will return a boolean value.

anyMatch() evaluates the condition in the stream until it finds its match and once the match is found, It exits the processing and returns a boolean value.

int [] arr = {1,2,3,4,5,6,7,8,9,11};
System.out.println("All numbers are greater than -1 : " + Arrays.stream(arr).allMatch(i-> i > -1));

System.out.println("Contains any numbers greater than 10 : " + Arrays.stream(arr).anyMatch(i-> i > 10));

References

Exit mobile version