The task is to identify and analyze orders placed within a specific date range and calculate various statistics like total order count, average order
meenakshi kalia
@ Wipro Lead Technical Solution Architect(GenAI) | Certified Scrum Master
Solution Using Stream API why Stream API
The Stream API in Java is a powerful tool for handling sequences of data in a declarative manner. Here’s a brief overview suitable for a Java architect:
### Key Features:
1. Functional Operations: Supports operations like map, filter, reduce, collect, forEach.
2. Laziness: Intermediate operations are lazy; they’re not executed until a terminal operation is invoked.
3. Parallel Processing: Streams can be processed in parallel using parallelStream.
4. Pipelines: Streams allow creating pipelines of operations which are efficient and readable.
### Best Practices:
1. Immutability: Use immutable collections to avoid side effects.
2. Parallel Streams: Use cautiously, ensure thread safety and performance benefits.
3. Short-Circuiting: Utilize short-circuiting operations (`findFirst`, anyMatch, noneMatch) for performance.
The Stream API enhances readability, maintainability, and performance of data processing in Java applications.
Here's a detailed example demonstrating various features of the Stream API in Java:
Example Scenario:
You have a list of employees, and you want to find the names of employees who are older than 30, sorted by their names, and collect them into a list.
### Employee Class:
```java
public class Employee {
private String name;
private int age;
// Constructor, getters, and setters
public Employee(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return "Employee{name='" + name + "', age=" + age + '}';
}
}
Main Class:
`
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StreamExample {
领英推荐
public static void main(String[] args) {
List<Employee> employees = Arrays.asList(
new Employee("Alice", 25),
new Employee("Bob", 35),
new Employee("Charlie", 30),
new Employee("David", 40)
);
List<String> employeeNames = employees.stream()
.filter(employee -> employee.getAge() > 30) // Filter employees older than 30
.sorted((e1, e2) -> e1.getName().compareTo(e2.getName())) // Sort by name
.map(Employee::getName) // Extract names
.collect(Collectors.toList()); // Collect into a list
employeeNames.forEach(System.out::println);
}
}
```
### Explanation:
1. Stream Creation: employees.stream() creates a stream from the list of employees.
2. Filtering: .filter(employee -> employee.getAge() > 30) filters employees older than 30.
3. Sorting: .sorted((e1, e2) -> e1.getName().compareTo(e2.getName())) sorts the filtered employees by their names.
4. Mapping: .map(Employee::getName) transforms the Employee objects into a stream of names.
5. Collecting: .collect(Collectors.toList()) collects the names into a list.
6. Printing: employeeNames.forEach(System.out::println) prints each name in the resulting list.
Solution
// Load orders from a data source
List<Order> orders = ...;
// Define the date range
LocalDate startDate = LocalDate.of(2024, 06, 01);
LocalDate endDate = LocalDate.now();
// Stream of orders within the date range
Stream<Order> filteredOrders = orders.stream() .filter(order -> order.getOrderDate().isAfter(startDate.minusDays(1)) // inclusive of start date
&& order.getOrderDate().isBefore(endDate.plusDays(1))); // exclusive of end date
// Total order count
long totalOrders = filteredOrders.count();
// Average order value (assuming Order has a getTotalPrice() method)
double averageOrderValue = filteredOrders.mapToDouble(Order::getTotalPrice).average().orElse(0.0);
// Map to product IDs and count occurrences (using Collectors.groupingBy)
Map<Long, Long> productCountMap = filteredOrders.flatMap(order -> order.getProducts().stream()).collect(Collectors.groupingBy(Product::getId, Collectors.counting()));
// Find most popular product (based on count)
Optional<Long> mostPopularProductId = productCountMap.entrySet().stream() .max(Comparator.comparingLong(Map.Entry::getValue)) .map(Map.Entry::getKey);
// Process further based on the collected statistics