Before reading this, I would recommend trying and learning what are imperative and declarative styles of programming. See Imperative vs Declarative
One of the powerful features the Java team included when bundling JDK 1.8 is the Streams API.
The purpose of streams is to process a sequence of elements by executing different kinds of operations on the elements.
The New Java package for streams is java.util.stream.
Let us see some of the important aspects of Streams API.
We have a few different ways to create a stream.
Following are the advantages of using Streams API.
List
, Map
, Set
, Arrays
, etc.parallelStream()
.Enough talk! Let us see an example 🤩
Let us see an example to understand the stream pipeline.
We have a list of the books and we are running some chain of methods on it like filter
, map
, etc. This chain of method calls is called a Stream Pipeline.
This is also called functional programming as we are passing functions.
Book
is a POJO with a constructor, getters, and setters.
class Book {
String title;
String author;
Integer year;
Integer copiesSoldInMillions;
Double rating;
Double costInEuros;
public Book(String title, String author, Integer year, Integer copiesSoldInMillions, Double rating, Double costInEuros) {
this.title = title;
this.author = author;
this.year = year;
this.copiesSoldInMillions = copiesSoldInMillions;
this.rating = rating;
this.costInEuros = costInEuros;
}
public String getAuthor() {
return author;
}
public Double getRating() {
return rating;
}
@Override
public String toString() {
return "Book{" +
"title='" + title + '\'' +
", author='" + author + '\'' +
", year=" + year +
", copiesSoldInMillions=" + copiesSoldInMillions +
", rating=" + rating +
", costInEuros=" + costInEuros +
'}';
}
}
Another class BookDatabase
for dummy data injection.
import java.util.Arrays;
import java.util.List;
public class BookDatabase {
public static List<Book> getAllBooks() {
return Arrays.asList(
new Book("Don Quixote", "Miguel de Cervantes", 1605, 500, 3.9, 9.99),
new Book("A Tale of Two Cities", "Charles Dickens", 1859, 200, 3.9, 10.0),
new Book("The Lord of the Rings", "J.R.R. Tolkien", 2001, 150, 4.0, 12.50),
new Book("The Little Prince", "Antoine de Saint-Exupery", 2016, 142, 4.4, 5.0),
new Book("The Dream of the Red Chamber", "Cao Xueqin", 1791, 100, 4.2, 10.0)
);
}
}
And finally out BookApplication
class that does the declarative programming or immutability on each book
object.
import java.util.List;
public class BookApplication {
public static void main(String[] args) {
List<Book> books = BookDatabase.getAllBooks();
books.stream()
.filter(book -> book.getRating() >= 4)
.map(Book::getAuthor)
.forEach(System.out::println);
}
}
Output:
J.R.R. Tolkien
Antoine de Saint-Exupery
Cao Xueqin
In the above example, we have a list of Book objects.
.stream(...)
to convert the list of Book
objects into a stream of objects..filter(...)
that take a Predicate and .map(...)
to get the filtered stream of objects..forEach(...)
to print all the objects.
First Published here