Java Streams API for data processing
package com.example.demo.examples;
import java.util.*;
import java.util.stream.Collectors;
public class StreamExamples {
public static class Product {
private String name;
private String category;
private double price;
private int quantity;
public Product(String name, String category, double price, int quantity) {
this.name = name;
this.category = category;
this.price = price;
this.quantity = quantity;
}
public String getName() { return name; }
public String getCategory() { return category; }
public double getPrice() { return price; }
public int getQuantity() { return quantity; }
}
public static void main(String[] args) {
List<Product> products = Arrays.asList(
new Product("Laptop", "Electronics", 999.99, 5),
new Product("Mouse", "Electronics", 29.99, 50),
new Product("Desk", "Furniture", 299.99, 10),
new Product("Chair", "Furniture", 199.99, 15),
new Product("Monitor", "Electronics", 399.99, 8)
);
// Filter and collect
List<Product> electronics = products.stream()
.filter(p -> p.getCategory().equals("Electronics"))
.collect(Collectors.toList());
// Map and transform
List<String> productNames = products.stream()
.map(Product::getName)
.collect(Collectors.toList());
// Filter, map, and sort
List<String> expensiveProducts = products.stream()
.filter(p -> p.getPrice() > 200)
.map(Product::getName)
.sorted()
.collect(Collectors.toList());
// Calculate sum
double totalValue = products.stream()
.mapToDouble(p -> p.getPrice() * p.getQuantity())
.sum();
// Find maximum
Optional<Product> mostExpensive = products.stream()
.max(Comparator.comparing(Product::getPrice));
// Group by category
Map<String, List<Product>> byCategory = products.stream()
.collect(Collectors.groupingBy(Product::getCategory));
// Count by category
Map<String, Long> countByCategory = products.stream()
.collect(Collectors.groupingBy(
Product::getCategory,
Collectors.counting()
));
// Average price by category
Map<String, Double> avgPriceByCategory = products.stream()
.collect(Collectors.groupingBy(
Product::getCategory,
Collectors.averagingDouble(Product::getPrice)
));
// Partition by price threshold
Map<Boolean, List<Product>> partitioned = products.stream()
.collect(Collectors.partitioningBy(p -> p.getPrice() > 100));
// Custom collector - concatenate names
String allNames = products.stream()
.map(Product::getName)
.collect(Collectors.joining(", ", "[", "]"));
// Parallel stream for large datasets
double parallelSum = products.parallelStream()
.mapToDouble(p -> p.getPrice() * p.getQuantity())
.sum();
// Reduce operation
Optional<Double> totalInventoryValue = products.stream()
.map(p -> p.getPrice() * p.getQuantity())
.reduce(Double::sum);
// Any match, all match, none match
boolean hasExpensive = products.stream()
.anyMatch(p -> p.getPrice() > 500);
boolean allInStock = products.stream()
.allMatch(p -> p.getQuantity() > 0);
// Find first
Optional<Product> firstElectronic = products.stream()
.filter(p -> p.getCategory().equals("Electronics"))
.findFirst();
System.out.println("Total inventory value: $" + totalValue);
System.out.println("Products by category: " + byCategory);
}
}
Java Streams provide a functional approach to processing collections with operations like filter, map, and reduce. I use stream() to create streams from collections and apply intermediate operations that are lazy and return new streams. Terminal operations like collect(), forEach(), and reduce() trigger execution. Method references and lambdas enable concise transformations. Collectors utility provides common reduction operations—toList, toSet, groupingBy, partitioningBy. Parallel streams with parallelStream() leverage multi-core processors. Streams are immutable and don't modify source collections. Optional handles potentially null results elegantly. Stream pipelines compose operations declaratively, improving readability and enabling compiler optimizations. This functional style reduces boilerplate and makes data transformations more expressive.