The release of Java 8 brought about numerous enhancements, with the Streams API emerging as a standout inclusion. One of its notable features is the filter method, which serves as a robust mechanism for handling collections in a functional manner. In the upcoming part, we will delve into the filter method, examining its application, advantages, and real-world uses.
What is the Streams API?
The Streams API introduces a fresh approach to handling data sequences in Java. This API empowers programmers to execute actions on collections such as Lists, Sets, and Maps in a declarative fashion by making use of functional programming principles. Operations in Streams are classified into two groups: intermediate and terminal operations. Intermediate operations yield a stream, enabling the chaining of methods, whereas terminal operations generate an outcome or a side effect, concluding the stream sequence.
Java Stream.filter Method
The filter method is considered an intermediate operation in streams, requiring a Predicate, a functional interface, as its parameter. A Predicate functions as a functional interface featuring a single abstract method, test, that yields a boolean outcome. When applied, the filter method examines each stream element and incorporates it into the output solely when the Predicate assesses it as true.
Signature
Below is the signature of the filter method in Stream:
Stream<T> filter(Predicate<? super T> predicate)
Parameter
The function requires a Predicate reference as a parameter, where Predicate represents a functional interface. This allows for the possibility of passing a lambda expression as well.
Return
It returns a new stream.
Java Stream.filter Example-1
In this instance, we are retrieving and looping through filtered data.
Example
import java.util.*;
class Product{
int id;
String name;
float price;
public Product(int id, String name, float price) {
this.id = id;
this.name = name;
this.price = price;
}
}
public class JavaStreamExample {
public static void main(String[] args) {
List<Product> productsList = new ArrayList<Product>();
//Adding Products
productsList.add(new Product(1,"HP Laptop",25000f));
productsList.add(new Product(2,"Dell Laptop",30000f));
productsList.add(new Product(3,"Lenevo Laptop",28000f));
productsList.add(new Product(4,"Sony Laptop",28000f));
productsList.add(new Product(5,"Apple Laptop",90000f));
productsList.stream()
.filter(p ->p.price> 30000) // filtering price
.map(pm ->pm.price) // fetching price
.forEach(System.out::println); // iterating price
}
}
Output:
90000.0
Java Stream.filter Example-2
In this instance, we are retrieving data that has been filtered and presenting it as a list.
Example
import java.util.*;
import java.util.stream.Collectors;
class Product{
int id;
String name;
float price;
public Product(int id, String name, float price) {
this.id = id;
this.name = name;
this.price = price;
}
}
public class JavaStreamExample {
public static void main(String[] args) {
List<Product> productsList = new ArrayList<Product>();
//Adding Products
productsList.add(new Product(1,"HP Laptop",25000f));
productsList.add(new Product(2,"Dell Laptop",30000f));
productsList.add(new Product(3,"Lenevo Laptop",28000f));
productsList.add(new Product(4,"Sony Laptop",28000f));
productsList.add(new Product(5,"Apple Laptop",90000f));
List<Float> pricesList = productsList.stream()
.filter(p ->p.price> 30000) // filtering price
.map(pm ->pm.price) // fetching price
.collect(Collectors.toList());
System.out.println(pricesList);
}
}
Output:
[90000.0]
Benefits of Using the filter Method
- Readability: The declarative nature of the Streams API makes the code more readable and concise.
- Reusability: The Predicate interface allows for reusable and modular code.
- Parallel Processing: Streams can be parallelized, enhancing performance on multi-core processors.
- Functional Programming: Embracing functional programming paradigms leads to cleaner and more maintainable code.
Conclusion
The filter function within the Java 8 Streams API serves as a flexible instrument for handling collections. It enables programmers to craft succinct, easily understandable, and effective code by making use of functional programming principles. Whether we are sorting through primitive data types, strings, or user-defined objects, the filter function offers a direct method to enhance the efficiency of data manipulation tasks. As we explore further into the Streams API, we will encounter additional robust operations that can revolutionize our data handling practices in Java.