Java案例如何使用Stream流?

wen java案例 13

Java Stream流使用案例详解

Stream流是Java 8引入的强大功能,用于以声明式方式处理集合数据,下面我将通过实际案例展示Stream流的各种用法。

Java案例如何使用Stream流?

基础操作案例

import java.util.*;
import java.util.stream.*;
public class StreamBasics {
    public static void main(String[] args) {
        // 创建一个示例数据集合
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Eva", "Frank");
        // 案例1:过滤出长度大于3的名字,并转换为大写
        System.out.println("=== 过滤并转换 ===");
        names.stream()
             .filter(name -> name.length() > 3)
             .map(String::toUpperCase)
             .forEach(System.out::println);
        // 案例2:获取前3个名字
        System.out.println("\n=== 取前3个 ===");
        names.stream()
             .limit(3)
             .forEach(System.out::println);
        // 案例3:跳过前2个名字
        System.out.println("\n=== 跳过前2个 ===");
        names.stream()
             .skip(2)
             .forEach(System.out::println);
    }
}

数字处理案例

import java.util.*;
import java.util.stream.*;
public class NumberStreamExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        // 案例4:过滤出偶数
        System.out.println("=== 偶数 ===");
        numbers.stream()
               .filter(n -> n % 2 == 0)
               .forEach(System.out::println);
        // 案例5:计算所有数的和
        int sum = numbers.stream()
                        .mapToInt(Integer::intValue)
                        .sum();
        System.out.println("\n总和: " + sum);
        // 案例6:计算平均值
        OptionalDouble average = numbers.stream()
                                       .mapToInt(Integer::intValue)
                                       .average();
        System.out.println("平均值: " + average.orElse(0));
        // 案例7:找出最大值和最小值
        Optional<Integer> max = numbers.stream().max(Integer::compareTo);
        Optional<Integer> min = numbers.stream().min(Integer::compareTo);
        System.out.println("最大值: " + max.orElse(0) + ", 最小值: " + min.orElse(0));
        // 案例8:去重
        List<Integer> duplicates = Arrays.asList(1, 2, 2, 3, 3, 4, 5, 5);
        System.out.println("\n去重后: " + 
            duplicates.stream().distinct().collect(Collectors.toList()));
    }
}

对象处理案例

import java.util.*;
import java.util.stream.*;
class Employee {
    private String name;
    private int age;
    private double salary;
    private String department;
    public Employee(String name, int age, double salary, String department) {
        this.name = name;
        this.age = age;
        this.salary = salary;
        this.department = department;
    }
    // getters and setters
    public String getName() { return name; }
    public int getAge() { return age; }
    public double getSalary() { return salary; }
    public String getDepartment() { return department; }
    @Override
    public String toString() {
        return String.format("%s (%d岁, %.2f元, %s)", name, age, salary, department);
    }
}
public class ObjectStreamExample {
    public static void main(String[] args) {
        List<Employee> employees = Arrays.asList(
            new Employee("张三", 30, 8000.0, "技术部"),
            new Employee("李四", 25, 6500.0, "市场部"),
            new Employee("王五", 35, 12000.0, "技术部"),
            new Employee("赵六", 28, 7500.0, "财务部"),
            new Employee("钱七", 40, 15000.0, "技术部"),
            new Employee("孙八", 32, 9000.0, "市场部")
        );
        // 案例9:按部门分组
        System.out.println("=== 按部门分组 ===");
        Map<String, List<Employee>> byDepartment = employees.stream()
            .collect(Collectors.groupingBy(Employee::getDepartment));
        byDepartment.forEach((dept, empList) -> {
            System.out.println(dept + ": " + empList);
        });
        // 案例10:计算每个部门的平均薪资
        System.out.println("\n=== 部门平均薪资 ===");
        Map<String, Double> avgSalaryByDept = employees.stream()
            .collect(Collectors.groupingBy(
                Employee::getDepartment,
                Collectors.averagingDouble(Employee::getSalary)
            ));
        avgSalaryByDept.forEach((dept, avg) -> 
            System.out.printf("%s: %.2f%n", dept, avg));
        // 案例11:找出薪资最高的员工
        System.out.println("\n=== 最高薪资员工 ===");
        Optional<Employee> highestPaid = employees.stream()
            .max(Comparator.comparingDouble(Employee::getSalary));
        highestPaid.ifPresent(emp -> System.out.println("最高薪资: " + emp));
        // 案例12:按年龄排序
        System.out.println("\n=== 按年龄排序 ===");
        employees.stream()
                .sorted(Comparator.comparingInt(Employee::getAge))
                .forEach(System.out::println);
    }
}

高级操作案例

import java.util.*;
import java.util.stream.*;
public class AdvancedStreamExample {
    public static void main(String[] args) {
        // 案例13:flatMap - 扁平化处理
        System.out.println("=== flatMap示例 ===");
        List<List<String>> nestedList = Arrays.asList(
            Arrays.asList("a", "b", "c"),
            Arrays.asList("d", "e", "f"),
            Arrays.asList("g", "h", "i")
        );
        List<String> flattenedList = nestedList.stream()
            .flatMap(Collection::stream)
            .collect(Collectors.toList());
        System.out.println("扁平化结果: " + flattenedList);
        // 案例14:reduce - 归约操作
        System.out.println("\n=== reduce示例 ===");
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        // 求和
        Optional<Integer> sum = numbers.stream()
            .reduce((a, b) -> a + b);
        System.out.println("求和结果: " + sum.orElse(0));
        // 带初始值的求和
        Integer sumWithIdentity = numbers.stream()
            .reduce(0, (a, b) -> a + b);
        System.out.println("带初始值求和: " + sumWithIdentity);
        // 案例15:并行流
        System.out.println("\n=== 并行流示例 ===");
        long count = numbers.parallelStream()
            .filter(n -> n > 2)
            .count();
        System.out.println("大于2的数字个数: " + count);
        // 案例16:收集到特定集合
        System.out.println("\n=== 收集到特定集合 ===");
        List<String> words = Arrays.asList("apple", "banana", "cherry", "date");
        // 收集到TreeSet(自动排序)
        TreeSet<String> sortedSet = words.stream()
            .collect(Collectors.toCollection(TreeSet::new));
        System.out.println("TreeSet结果: " + sortedSet);
        // 案例17:统计信息
        System.out.println("\n=== 统计信息 ===");
        IntSummaryStatistics stats = numbers.stream()
            .mapToInt(Integer::intValue)
            .summaryStatistics();
        System.out.println("统计信息: " + stats);
        System.out.println("最大值: " + stats.getMax());
        System.out.println("最小值: " + stats.getMin());
        System.out.println("平均值: " + stats.getAverage());
        System.out.println("总数: " + stats.getCount());
        // 案例18:分组并计数
        System.out.println("\n=== 分组计数 ===");
        List<String> items = Arrays.asList(
            "apple", "banana", "apple", "orange", "banana", "apple"
        );
        Map<String, Long> itemCount = items.stream()
            .collect(Collectors.groupingBy(
                Function.identity(),
                Collectors.counting()
            ));
        System.out.println("各元素出现次数: " + itemCount);
    }
}

实际业务场景案例

import java.util.*;
import java.util.stream.*;
// 订单相关类
class Order {
    private String orderId;
    private String customerName;
    private double amount;
    private String status;
    private LocalDateTime createTime;
    public Order(String orderId, String customerName, double amount, String status) {
        this.orderId = orderId;
        this.customerName = customerName;
        this.amount = amount;
        this.status = status;
        this.createTime = LocalDateTime.now();
    }
    // getters...
    public String getOrderId() { return orderId; }
    public String getCustomerName() { return customerName; }
    public double getAmount() { return amount; }
    public String getStatus() { return status; }
    public LocalDateTime getCreateTime() { return createTime; }
    @Override
    public String toString() {
        return String.format("订单[%s] %s - %.2f元 (%s)", 
            orderId, customerName, amount, status);
    }
}
public class BusinessStreamExample {
    public static void main(String[] args) {
        List<Order> orders = Arrays.asList(
            new Order("001", "张三", 500.0, "已完成"),
            new Order("002", "李四", 1200.0, "待付款"),
            new Order("003", "张三", 300.0, "已完成"),
            new Order("004", "王五", 2000.0, "待发货"),
            new Order("005", "张三", 800.0, "已完成"),
            new Order("006", "李四", 1500.0, "已完成")
        );
        // 场景1:查找某个客户的所有已完成订单
        System.out.println("=== 张三的已完成订单 ===");
        orders.stream()
            .filter(o -> "张三".equals(o.getCustomerName()))
            .filter(o -> "已完成".equals(o.getStatus()))
            .forEach(System.out::println);
        // 场景2:计算所有已完成订单的总金额
        double completedAmount = orders.stream()
            .filter(o -> "已完成".equals(o.getStatus()))
            .mapToDouble(Order::getAmount)
            .sum();
        System.out.println("\n已完成订单总金额: " + completedAmount);
        // 场景3:统计每个客户的订单总金额
        System.out.println("\n=== 客户订单总金额 ===");
        Map<String, Double> customerTotal = orders.stream()
            .collect(Collectors.groupingBy(
                Order::getCustomerName,
                Collectors.summingDouble(Order::getAmount)
            ));
        customerTotal.forEach((customer, total) -> 
            System.out.printf("%s: %.2f元%n", customer, total));
        // 场景4:找出金额最大的订单
        System.out.println("\n=== 最大金额订单 ===");
        Optional<Order> maxOrder = orders.stream()
            .max(Comparator.comparingDouble(Order::getAmount));
        maxOrder.ifPresent(order -> System.out.println("最大金额订单: " + order));
        // 场景5:按状态分组并统计各状态数量
        System.out.println("\n=== 各状态订单数量 ===");
        Map<String, Long> statusCount = orders.stream()
            .collect(Collectors.groupingBy(
                Order::getStatus,
                Collectors.counting()
            ));
        statusCount.forEach((status, count) -> 
            System.out.printf("%s: %d个%n", status, count));
    }
}

Stream流常用操作总结

操作 说明 示例
filter() 过滤元素 stream.filter(x -> x > 5)
map() 转换元素 stream.map(String::toUpperCase)
flatMap() 扁平化流 stream.flatMap(Collection::stream)
distinct() 去重 stream.distinct()
sorted() 排序 stream.sorted()
limit() 限制数量 stream.limit(5)
skip() 跳过元素 stream.skip(3)
forEach() 遍历 stream.forEach(System.out::println)
collect() 收集结果 stream.collect(Collectors.toList())
reduce() 归约操作 stream.reduce(0, (a,b) -> a+b)
count() 计数 stream.count()
anyMatch() 任意匹配 stream.anyMatch(x -> x > 0)
allMatch() 全部匹配 stream.allMatch(x -> x > 0)
noneMatch() 无匹配 stream.noneMatch(x -> x < 0)
findFirst() 找第一个 stream.findFirst()
findAny() 找任意一个 stream.findAny()

使用建议

  1. 链式操作:Stream流支持链式调用,使代码更简洁易读
  2. 惰性求值:中间操作(如filter、map)是惰性的,只有遇到终止操作(如collect、forEach)才执行
  3. 并行处理:使用parallelStream()可以利用多核CPU提高处理效率
  4. 避免副作用:尽量使用无状态的lambda表达式,避免在流操作中修改外部变量
  5. 适当使用:对于简单操作,传统循环可能更直观;复杂的数据处理则优先使用Stream流

这些案例涵盖了Stream流的大部分常用功能,通过实际代码演示了如何在Java中高效地使用Stream API处理数据集合。

抱歉,评论功能暂时关闭!