Java Stream API 详解
一、Stream API 概述
在实际开发中,我们经常会遇到这样的场景:有一个商品列表,需要筛选出价格低于某个值的商品,按价格排序后获取商品名称。
这种需求在以往通常需要通过多层循环和条件判断来实现,代码冗长且难以维护。Java 8 引入的 Stream API 提供了一种优雅的解决方案,它允许我们以声明式的方式处理数据集合。
让我们先定义一个商品类:
``` package com.example.model;
public class Product {
private final String productName;
private final boolean inStock;
private final int price;
private final Category category;
public Product(String productName, boolean inStock, int price, Category category) {
this.productName = productName;
this.inStock = inStock;
this.price = price;
this.category = category;
}
public String getProductName() {
return productName;
}
public boolean isInStock() {
return inStock;
}
public int getPrice() {
return price;
}
public Category getCategory() {
return category;
}
public enum Category {ELECTRONICS, CLOTHING, FOOD, BOOKS}
@Override
public String toString() {
return "Product{" +
"productName='" + productName + '\'' +
", inStock=" + inStock +
", price=" + price +
", category=" + category +
'}';
}
}
View Code```
package com.example.stream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
public class StreamDemo {
public static void main(String[] args) {
List<Product> productList = Arrays.asList(
new Product("Laptop", false, 800, Product.Category.ELECTRONICS),
new Product("Smartphone", false, 700, Product.Category.ELECTRONICS),
new Product("T-Shirt", true, 400, Product.Category.CLOTHING),
new Product("Jeans", true, 530, Product.Category.CLOTHING),
new Product("Apple", true, 350, Product.Category.FOOD),
new Product("Banana", true, 120, Product.Category.FOOD),
new Product("Novel", true, 550, Product.Category.BOOKS),
new Product("Headphones", false, 300, Product.Category.ELECTRONICS),
new Product("Textbook", false, 450, Product.Category.BOOKS));
List<String> affordableProducts = getAffordableProducts(productList);
System.out.println(affordableProducts);
List<String> affordableProducts2 = getAffordableProductsWithStream(productList);
System.out.println(affordableProducts2);
}
/**
* 使用传统方式实现
* 筛选价格低于400的商品,按价格排序,返回商品名称列表
*/
private static List<String> getAffordableProducts(List<Product> productList) {
List<Product> filteredProducts = new ArrayList<>();
for (Product product : productList) {
if (product.getPrice() < 400) {
filteredProducts.add(product);
}
}
filteredProducts.sort(Comparator.comparingInt(Product::getPrice));
List<String> result = new ArrayList<>();
for (Product product : filteredProducts) {
result.add(product.getProductName());
}
return result;
}
/**
* 使用 Stream API 实现
*/
private static List<String> getAffordableProductsWithStream(List<Product> productList) {
return productList.stream()
.filter(product -> product.getPrice() < 400)
.sorted(Comparator.comparingInt(Product::getPrice))
.map(Product::getProductName)
.collect(Collectors.toList());
}
}
console打印:
[Banana, Headphones, Apple]
[Banana, Headphones, Apple]
Stream API 是对集合功能的增强,它提供了强大的数据处理能力。Stream 的一个重要特性是支持并行处理,能够充分利用多核处理器的优势,同时开发者无需关心底层的并行实现细节。
二、Stream API 常用操作
接下来我们通过具体示例介绍 Stream 的核心方法:
package com.example.stream;
import java.util.*;
import java.util.stream.Stream;
public class StreamOperations {
public static void main(String[] args) {
List<Product> productList = Arrays.asList(
new Product("Laptop", false, 800, Product.Category.ELECTRONICS),
new Product("Smartphone", false, 700, Product.Category.ELECTRONICS),
new Product("T-Shirt", true, 400, Product.Category.CLOTHING),
new Product("Jeans", true, 530, Product.Category.CLOTHING),
new Product("Apple", true, 350, Product.Category.FOOD),
new Product("Banana", true, 120, Product.Category.FOOD),
new Product("Novel", true, 550, Product.Category.BOOKS),
new Product("Headphones", false, 300, Product.Category.ELECTRONICS),
new Product("Textbook", false, 450, Product.Category.BOOKS));
System.out.println("Method 1 - Most expensive: " + findMostExpensive(productList));
System.out.println("Method 2 - Most expensive: " + findMostExpensiveAlternative(productList));
System.out.println("Has expensive items (>600): " + hasExpensiveItems(productList));
System.out.println("All items affordable (>400): " + areAllAffordable(productList));
System.out.println("---------------------------------------");
// 创建 Stream 的两种方式
Stream<Product> directStream = Stream.of(
new Product("Camera", false, 600, Product.Category.ELECTRONICS),
new Product("Tablet", false, 450, Product.Category.ELECTRONICS));
directStream.forEach(System.out::println);
}
/**
* 查找价格最高的商品名称 - 方式一
*/
private static String findMostExpensive(List<Product> productList) {
return productList.stream()
.max(Comparator.comparingInt(Product::getPrice))
.get()
.getProductName();
}
/**
* 查找价格最高的商品名称 - 方式二
*/
private static String findMostExpensiveAlternative(List<Product> productList) {
Optional<Product> maxProduct = productList.stream()
.sorted((p1, p2) -> p2.getPrice() - p1.getPrice())
.findFirst();
return maxProduct.get().getProductName();
}
/**
* 判断是否存在价格大于600的商品
*/
private static boolean hasExpensiveItems(List<Product> productList) {
return productList.stream().anyMatch(product -> product.getPrice() > 600);
}
/**
* 判断所有商品价格是否都大于400
*/
private static boolean areAllAffordable(List<Product> productList) {
return productList.stream().allMatch(product -> product.getPrice() > 400);
}
}
打印结果:
Method 1 - Most expensive: Laptop
Method 2 - Most expensive: Laptop
Has expensive items (>600): true
All items affordable (>400): false
---------------------------------------
Product{productName='Camera', inStock=false, price=600, category=ELECTRONICS}
Product{productName='Tablet', inStock=false, price=450, category=ELECTRONICS}
--