全栈开发

Java stream操作示例

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>stream-tutorial</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <junit.version>5.10.0</junit.version>
    </properties>

    <dependencies>
        <!-- JUnit 5 -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- Maven Surefire Plugin for JUnit 5 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.2.2</version>
            </plugin>
        </plugins>
    </build>
</project>

测试类:StreamCollectorsTest.java

import org.junit.jupiter.api.Test;

import java.util.*;
import java.util.stream.Collectors;

import static org.junit.jupiter.api.Assertions.*;

/**
 * Java Stream + Collectors 学习示例
 * 不依赖 Spring,纯 JUnit 5 测试
 */
public class StreamCollectorsTest {

    // 模拟数据
    private static List<MonitorRule> createSampleRules() {
        return Arrays.asList(
            new MonitorRule(1L, "user_01", "TYPE", "users", true),
            new MonitorRule(2L, "user_02", "CUSTOM", "users", true),
            new MonitorRule(3L, "order_01", "LENGTH", "orders", true),
            new MonitorRule(4L, "order_02", "CUSTOM", "orders", false),
            new MonitorRule(5L, "user_03", "ENUM", "users", true)
        );
    }
    
    @Test
    public void test01() {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "Bob");
        // 转为List
        List<String> list = names.stream().collect(Collectors.toList());
        System.out.println(list);
        // 转为Set去重
        Set<String> set = names.stream().collect(Collectors.toSet());
        System.out.println(set);
        // 拼接字符串
        String joined = names.stream().collect(Collectors.joining(","));
        System.out.println(joined);
    }

    /**
     * 示例1: 按表名分组,并对每组排序(基础类型在前,CUSTOM 在后)
     */
    @Test
    public void testGroupingAndSorting() {
        List<MonitorRule> allRules = createSampleRules();

        Map<String, List<MonitorRule>> grouped = allRules.stream()
            .filter(MonitorRule::getEnabled) // 只取启用的规则
            .collect(
                Collectors.groupingBy(
                    MonitorRule::getTableName,
                    Collectors.collectingAndThen(
                        Collectors.toList(),
                        list -> {
                            // 排序:非 CUSTOM 优先
                            list.sort((r1, r2) -> {
                                boolean isCustom1 = "CUSTOM".equals(r1.getRuleType());
                                boolean isCustom2 = "CUSTOM".equals(r2.getRuleType());
                                if (isCustom1 && !isCustom2) return 1;
                                if (!isCustom1 && isCustom2) return -1;
                                return 0; // 同类型保持原顺序
                            });
                            return list;
                        }
                    )
                )
            );

        // 验证 users 表:TYPE, ENUM 在前,CUSTOM 在后
        List<MonitorRule> userRules = grouped.get("users");
        assertEquals(3, userRules.size());
        assertEquals("TYPE", userRules.get(0).getRuleType());
        assertEquals("ENUM", userRules.get(1).getRuleType());
        assertEquals("CUSTOM", userRules.get(2).getRuleType());

        // orders 表只有 1 条启用的规则(LENGTH)
        List<MonitorRule> orderRules = grouped.get("orders");
        assertEquals(1, orderRules.size());
        assertEquals("LENGTH", orderRules.get(0).getRuleType());

        System.out.println("分组+排序结果:");
        grouped.forEach((table, rules) ->
            System.out.println(table + " -> " + 
                rules.stream().map(MonitorRule::getRuleCode).collect(Collectors.joining(", ")))
        );
    }

    /**
     * 示例2: 统计每个表的规则数量
     */
    @Test
    public void testCountingByTable() {
        List<MonitorRule> rules = createSampleRules();
        Map<String, Long> counts = rules.stream()
            .collect(Collectors.groupingBy(
                MonitorRule::getTableName,
                Collectors.counting()
            ));

        assertEquals(3L, counts.get("users"));
        assertEquals(2L, counts.get("orders"));
        System.out.println("规则数量统计: " + counts);
    }

    /**
     * 示例3: 将规则按启用状态分区
     */
    @Test
    public void testPartitioningByEnabled() {
        List<MonitorRule> rules = createSampleRules();
        Map<Boolean, List<MonitorRule>> partition = rules.stream()
            .collect(Collectors.partitioningBy(MonitorRule::getEnabled));

        assertEquals(4, partition.get(true).size());   // 启用的
        assertEquals(1, partition.get(false).size());  // 未启用的
        System.out.println("启用规则数: " + partition.get(true).size());
    }

    /**
     * 示例4: 拼接所有启用规则的 ruleCode
     */
    @Test
    public void testJoiningRuleCodes() {
        List<MonitorRule> rules = createSampleRules();
        String codes = rules.stream()
            .filter(MonitorRule::getEnabled)
            .map(MonitorRule::getRuleCode)
            .collect(Collectors.joining(", "));

        assertEquals("user_01, user_02, order_01, user_03", codes);
        System.out.println("启用的规则编码: " + codes);
    }
}

/**
 * 简化版 MonitorRule(仅用于测试)
 */
class MonitorRule {
    private Long id;
    private String ruleCode;
    private String ruleType;
    private String tableName;
    private Boolean enabled;

    public MonitorRule(Long id, String ruleCode, String ruleType, String tableName, Boolean enabled) {
        this.id = id;
        this.ruleCode = ruleCode;
        this.ruleType = ruleType;
        this.tableName = tableName;
        this.enabled = enabled;
    }

    // Getters
    public Long getId() { return id; }
    public String getRuleCode() { return ruleCode; }
    public String getRuleType() { return ruleType; }
    public String getTableName() { return tableName; }
    public Boolean getEnabled() { return enabled; }

    @Override
    public String toString() {
        return "MonitorRule{" +
                "ruleCode='" + ruleCode + '\'' +
                ", ruleType='" + ruleType + '\'' +
                ", tableName='" + tableName + '\'' +
                ", enabled=" + enabled +
                '}';
    }
}