这个项目是一个订单处理和数据分析系统,主要演示了Java 8 Stream API和Lambda表达式的实际应用场景。主要功能包括:订单状态跟踪和统计、 客户消费行为分析、 商品销售数据统计、 时间维度数据分析。
1. 商品订单处理示
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
// 商品类
class Product {
private Long id;
private String name;
private BigDecimal price;
private String category;
public Product(Long id, String name, BigDecimal price, String category) {
this.id = id;
this.name = name;
this.price = price;
this.category = category;
}
// Getters
public Long getId() { return id; }
public String getName() { return name; }
public BigDecimal getPrice() { return price; }
public String getCategory() { return category; }
@Override
public String toString() {
return "Product{" +
"id=" + id +
", name='" + name + '\'' +
", price=" + price +
", category='" + category + '\'' +
'}';
}
}
// 订单项类
class OrderItem {
private Long productId;
private String productName;
private BigDecimal price;
private Integer quantity;
public OrderItem(Long productId, String productName, BigDecimal price, Integer quantity) {
this.productId = productId;
this.productName = productName;
this.price = price;
this.quantity = quantity;
}
// Getters
public Long getProductId() { return productId; }
public String getProductName() { return productName; }
public BigDecimal getPrice() { return price; }
public Integer getQuantity() { return quantity; }
public BigDecimal getSubtotal() {
return price.multiply(BigDecimal.valueOf(quantity));
}
@Override
public String toString() {
return "OrderItem{" +
"productId=" + productId +
", productName='" + productName + '\'' +
", price=" + price +
", quantity=" + quantity +
", subtotal=" + getSubtotal() +
'}';
}
}
// 订单类
class Order {
private Long id;
private String customerName;
private LocalDateTime orderTime;
private List<OrderItem> items;
private String status;
public Order(Long id, String customerName, LocalDateTime orderTime,
List<OrderItem> items, String status) {
this.id = id;
this.customerName = customerName;
this.orderTime = orderTime;
this.items = items;
this.status = status;
}
// Getters
public Long getId() { return id; }
public String getCustomerName() { return customerName; }
public LocalDateTime getOrderTime() { return orderTime; }
public List<OrderItem> getItems() { return items; }
public String getStatus() { return status; }
public BigDecimal getTotalAmount() {
return items.stream()
.map(OrderItem::getSubtotal)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
@Override
public String toString() {
return "Order{" +
"id=" + id +
", customerName='" + customerName + '\'' +
", orderTime=" + orderTime +
", items=" + items +
", status='" + status + '\'' +
", totalAmount=" + getTotalAmount() +
'}';
}
}
public class OrderProcessingDemo {
public static void main(String[] args) {
// 创建商品数据
List<Product> products = Arrays.asList(
new Product(1L, "iPhone 14", new BigDecimal("5999.00"), "电子产品"),
new Product(2L, "MacBook Pro", new BigDecimal("12999.00"), "电子产品"),
new Product(3L, "Nike运动鞋", new BigDecimal("899.00"), "服装鞋帽"),
new Product(4L, "Java编程思想", new BigDecimal("99.00"), "图书"),
new Product(5L, "咖啡机", new BigDecimal("1299.00"), "家电")
);
// 创建订单数据
List<Order> orders = Arrays.asList(
new Order(1L, "张三", LocalDateTime.of(2023, 10, 1, 10, 30),
Arrays.asList(
new OrderItem(1L, "iPhone 14", new BigDecimal("5999.00"), 1),
new OrderItem(4L, "Java编程思想", new BigDecimal("99.00"), 2)
), "已完成"),
new Order(2L, "李四", LocalDateTime.of(2023, 10, 2, 14, 15),
Arrays.asList(
new OrderItem(2L, "MacBook Pro", new BigDecimal("12999.00"), 1),
new OrderItem(3L, "Nike运动鞋", new BigDecimal("899.00"), 1)
), "已发货"),
new Order(3L, "王五", LocalDateTime.of(2023, 10, 3, 9, 45),
Arrays.asList(
new OrderItem(5L, "咖啡机", new BigDecimal("1299.00"), 2)
), "待付款"),
new Order(4L, "赵六", LocalDateTime.of(2023, 10, 4, 16, 20),
Arrays.asList(
new OrderItem(1L, "iPhone 14", new BigDecimal("5999.00"), 1),
new OrderItem(5L, "咖啡机", new BigDecimal("1299.00"), 1)
), "已完成")
);
// 1. 计算所有已完成订单的总金额
BigDecimal totalCompletedAmount = orders.stream()
.filter(order -> "已完成".equals(order.getStatus()))
.map(Order::getTotalAmount)
.reduce(BigDecimal.ZERO, BigDecimal::add);
System.out.println("已完成订单总金额: " + totalCompletedAmount);
// 2. 查找消费最高的客户
Optional<String> topCustomer = orders.stream()
.collect(Collectors.groupingBy(
Order::getCustomerName,
Collectors.reducing(BigDecimal.ZERO, Order::getTotalAmount, BigDecimal::add)
))
.entrySet()
.stream()
.max(Map.Entry.comparingByValue())
.map(Map.Entry::getKey);
System.out.println("消费最高的客户: " + topCustomer.orElse("无"));
// 3. 按月份统计订单数量
Map<Integer, Long> ordersByMonth = orders.stream()
.collect(Collectors.groupingBy(
order -> order.getOrderTime().getMonthValue(),
Collectors.counting()
));
System.out.println("按月份统计订单数量: " + ordersByMonth);
// 4. 统计各商品类别的销售数量
Map<String, Integer> salesByCategory = orders.stream()
.flatMap(order -> order.getItems().stream())
.collect(Collectors.groupingBy(
item -> products.stream()
.filter(p -> p.getId().equals(item.getProductId()))
.findFirst()
.map(Product::getCategory)
.orElse("未知"),
Collectors.summingInt(OrderItem::getQuantity)
));
System.out.println("各商品类别销售数量: " + salesByCategory);
// 5. 查找热门商品(销量前3)
List<String> popularProducts = orders.stream()
.flatMap(order -> order.getItems().stream())
.collect(Collectors.groupingBy(
OrderItem::getProductName,
Collectors.summingInt(OrderItem::getQuantity)
))
.entrySet()
.stream()
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
.limit(3)
.map(Map.Entry::getKey)
.collect(Collectors.toList());
System.out.println("热门商品TOP3: " + popularProducts);
// 6. 按订单金额区间分类
Map<String, List<Order>> ordersByAmountRange = orders.stream()
.collect(Collectors.groupingBy(order -> {
BigDecimal total = order.getTotalAmount();
if (total.compareTo(new BigDecimal("5000")) < 0) {
return "小额订单(<5000)";
} else if (total.compareTo(new BigDecimal("10000")) < 0) {
return "中额订单(5000-10000)";
} else {
return "大额订单(>10000)";
}
}));
System.out.println("订单金额区间分类:");
ordersByAmountRange.forEach((range, orderList) ->
System.out.println(" " + range + ": " + orderList.size() + "笔"));
// 7. 获取最近一周的订单
LocalDateTime oneWeekAgo = LocalDateTime.now().minusWeeks(1);
List<Order> recentOrders = orders.stream()
.filter(order -> order.getOrderTime().isAfter(oneWeekAgo))
.collect(Collectors.toList());
System.out.println("最近一周订单数: " + recentOrders.size());
// 8. 计算平均订单金额
OptionalDouble avgOrderAmount = orders.stream()
.mapToDouble(order -> order.getTotalAmount().doubleValue())
.average();
System.out.println("平均订单金额: " + avgOrderAmount.orElse(0.0));
}
}
解析
基于提供的代码,用到了以下Stream API相关内容:
Stream创建操作
Arrays.asList().stream()- 从集合创建流items.stream()- 从Order对象的items列表创建流products.stream()- 从products列表创建流
中间操作(Intermediate Operations)
filter()- 过滤满足条件的元素- 示例:
.filter(order -> "已完成".equals(order.getStatus())) - 示例:
.filter(order -> order.getOrderTime().isAfter(oneWeekAgo))
- 示例:
map()- 元素转换操作- 示例:
.map(Order::getTotalAmount) - 示例:
.map(OrderItem::getProductName) - 示例:
.map(p -> p.getId().equals(item.getProductId()))
- 示例:
flatMap()- 扁平化流操作- 示例:
.flatMap(order -> order.getItems().stream())
- 示例:
sorted()- 排序操作- 示例:
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
- 示例:
limit()- 限制结果数量- 示例:
.limit(3)
- 示例:
终端操作(Terminal Operations)
reduce()- 归约操作- 示例:
.reduce(BigDecimal.ZERO, BigDecimal::add)
- 示例:
collect()- 收集操作- 示例:
.collect(Collectors.toList()) - 示例:
.collect(Collectors.groupingBy(...)) - 示例:
.collect(Collectors.summingInt(OrderItem::getQuantity)) - 示例:
.collect(Collectors.counting())
- 示例:
forEach()- 遍历操作- 示例:
.forEach((range, orderList) -> ...)
- 示例:
max()- 查找最大值- 示例:
.max(Map.Entry.comparingByValue())
- 示例:
count()- 计数操作- 示例:
.count()
- 示例:
average()- 计算平均值- 示例:
.average()
- 示例:
Collector收集器
Collectors.groupingBy()- 分组收集器Collectors.summingInt()- 求和收集器Collectors.counting()- 计数收集器Collectors.reducing()- 归约收集器Collectors.toList()- 转换为列表
数值流操作
mapToDouble()- 转换为DoubleStream- 示例:
.mapToDouble(order -> order.getTotalAmount().doubleValue())
- 示例:
2. 数据处理和分析示例
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class DataAnalysisDemo {
public static void main(String[] args) {
// 1. 数值流操作
System.out.println("=== 数值流操作 ===");
int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// 计算偶数的平方和
int evenSquareSum = Arrays.stream(numbers)
.filter(n -> n % 2 == 0)
.map(n -> n * n)
.sum();
System.out.println("偶数平方和: " + evenSquareSum);
// 2. 字符串处理
System.out.println("\n=== 字符串处理 ===");
List<String> words = Arrays.asList("Java", "Stream", "API", "Lambda", "Functional");
// 过滤长度大于4的单词并转为大写
List<String> filteredWords = words.stream()
.filter(word -> word.length() > 4)
.map(String::toUpperCase)
.sorted()
.collect(Collectors.toList());
System.out.println("处理后的单词: " + filteredWords);
// 3. 扁平化处理
System.out.println("\n=== 扁平化处理 ===");
List<List<String>> wordGroups = Arrays.asList(
Arrays.asList("Hello", "World"),
Arrays.asList("Java", "Programming"),
Arrays.asList("Stream", "API", "Example")
);
List<String> flattenedWords = wordGroups.stream()
.flatMap(Collection::stream)
.collect(Collectors.toList());
System.out.println("扁平化后的单词: " + flattenedWords);
// 4. 生成无限流
System.out.println("\n=== 无限流处理 ===");
// 生成前10个斐波那契数
List<Integer> fibonacci = Stream.iterate(
new int[]{0, 1},
arr -> new int[]{arr[1], arr[0] + arr[1]}
)
.limit(10)
.map(arr -> arr[0])
.collect(Collectors.toList());
System.out.println("斐波那契数列: " + fibonacci);
// 5. 并行流处理
System.out.println("\n=== 并行流处理 ===");
long startTime = System.currentTimeMillis();
List<Integer> largeList = IntStream.range(1, 1000000)
.boxed()
.collect(Collectors.toList());
// 串行处理
long serialCount = largeList.stream()
.filter(n -> isPrime(n))
.count();
long serialTime = System.currentTimeMillis() - startTime;
// 并行处理
startTime = System.currentTimeMillis();
long parallelCount = largeList.parallelStream()
.filter(n -> isPrime(n))
.count();
long parallelTime = System.currentTimeMillis() - startTime;
System.out.println("串行处理耗时: " + serialTime + "ms, 质数个数: " + serialCount);
System.out.println("并行处理耗时: " + parallelTime + "ms, 质数个数: " + parallelCount);
}
// 判断是否为质数的辅助方法
private static boolean isPrime(int number) {
if (number <= 1) return false;
if (number <= 3) return true;
if (number % 2 == 0 || number % 3 == 0) return false;
for (int i = 5; i * i <= number; i += 6) {
if (number % i == 0 || number % (i + 2) == 0) {
return false;
}
}
return true;
}
}