Java 8 — Stream APIs

Abdalrhmanalkraien
CodeX
Published in
5 min readFeb 12, 2023
Java8 Stream APIs

overview

When Java 8 came into this world, it comes to provide us with more features, flexibility, and comfortable to work with it and save effort and time.

one of these features is Stream, Stream provides us with more control over our data inside the application using APIs.

so let's go to see how the Stream APIs work, and understand what can we do using Stream.

What is Stream in Java?

Streams are used to process a collection of objects, so to use a stream we need to know about the collection and lambda expression in java, to control the data.

The stream is not a data structure, and when using a stream the original data does not change too. Rather than sort and filter the data in variables, you can sort the data by the stream in one line and collect the data after implementing all the processes you need on the data.

The stream has many bulk operations like foreach() , filter() , map() , flatMap() and other operations. and have the collection method convert your data to many data structure types like List , Set , LinkedList using

What are the stream types?

we have two types of streams, all type has own jobs.

  • Terminal Intermediate operation: will produce a result or side effect, such as count() or forEach(Consumer)

Terminal Operation : Stream --> Result

forEach(), toArray(), reduce(), collect(), min(), max(), count(), anyMatch(), allMatch(), noneMatch(), findFirst(), findAny() all of these operations are Terminal operations.

  • Non-Terminal/Intermediate operation: will transform a stream into another stream, such as filter(Predicate).

Non-Terminal Operation : Stream --> Stream.

map() , filter() , flatMap() ,distinct(), sorted(), limit(), skip() all of these operations are Non-Terminal operations.

Stream types

Stream format

So now we need to see how we can create our Stream and control it, In this part, I will cover the common operations in the stream, and in another article, I will throw deeply into the Stream to make sure understand it.

To define stream in the application we have two ways, the first one user stream the key word with our collection and a second way to define stream directly.

For example:

  • convert collection: ourcollection.stream()
  • direct way : Stream.of(1,12,3,5,56)

Stream Operation

So like I said, we have many operations in the stream, and in this article, I will explain the common terminal and non-terminal intermediate operations.

I have the following code, and I will explain it, so please read it and continue when being ready.

List<Integer> numbers = Arrays.asList(-1, 3, 5, 7, 9, 2, 4, 6, 8);

List<Integer> filterNumberList = numbers
.stream()
.filter(number -> number >= 10)
.collect(Collectors.toList());

List<String> programmingLanguage = Arrays
.asList("JAVA", "PHP", "PYTHON", "GO");

List<String> programmingLanguageAfterMap = programmingLanguage
.stream()
.map(lang -> lang.lowerCase())
.forEach(lang ->{

System.out.println("programmingLanguageAfterMap : ".concat(lang));
});

List<Integer> sortedListNumber = numbers
.stream()
.sorted()
.collect(Collectors.toList());

Predicate<Integer> predicateToGetOddNumbers = integer -> integer % 2 != 0;
List<Integer> oddNumbersUsingPredicate = numbers
.stream()
.filter(predicateToGetOddNumbers)
.collect(Collectors.toList());


List<Integer> distinctOddNumbersUsingPredicate = numbers
.stream()
.filter(predicateToGetOddNumbers)
.distinct()
.collect(Collectors.toList());

▶️ Collect Operation

In this example code, I have used the collect method in many places. Whenever I want to assign the intermediate resulting stream into a collection, I have used collect operation.

▶️ Map Operation

I have used this operation to convert the elements in the stream into another set of objects like converting words from Upper case to lower case. The only thing we need to understand is the way to define it.

▶️ Sorted Operation

I used the sorted function to sort the integers numbers. By default, it uses the basic integer and string comparison. But we can change the implementation of this method. In the code, as an example, I have defined sortedListNumber sorting numbers in the list.

▶️ Filter Operation

This is a very useful function that can be used to select elements that we want. The filter method takes a Predicate as a parameter. What is it? Predicate is a Functional Interface in Java. (I think you have a basic understanding of Lambda Expressions!) Simply it has only one method which returns a boolean value. So, we can pass a lambda expression which returns a boolean value, as the parameter for the filter method. I have defined the predicateToGetOddNumbers variable as a Predicate to return true if the element is odd.

▶️ ForEach Operation

This method is also useful to loop over a collection. Simply it takes a Consumer as the argument. It can be separately implemented and provided into the forEach loop. Otherwise, we can implement the logic as a lambda expression, within the forEach loop.

Stream Loop and for Loop

The stream is very nice, and it is worth comparing with java puer code, and this section I want to compare between forEach in the stream, and for loop, and we need to filter the data using filter by streamand simple if statment.

Look at the following code to see the difference between to ways.

public List<people> oldestThanAge(List<Pepole> people, Integer age) {

return people
.filter( p -> p.age() < 19)
.collect(toList());
vs

List<People> filtered = new ArrayList<>();
for(People p : people) {
if(p.age() < 19) {
filtered.add(p);
}
}

return filtered;
}

The streams Roles

  • Intermediate operations are Lazy — all intermediate operations will NOT be executed without a terminal operation at the end.
  • In a way, an intermediate operation is memorized and is recalled as soon as a terminal operation is invoked.
  • You can chain multiple intermediate operations and none of them will do anything until you invoke a terminal operation. At that time, all of the intermediate operations that you invoked earlier will be invoked along with the terminal operation.

Finally, don’t forget to share and clap the articles and you can clap 50 times on each article. and you find my LinkedIn here.

--

--

Abdalrhmanalkraien
CodeX
Writer for

I am a Java Developer and DevOps Engineer. I used the latest Technology for build completed development or Deployment