文章
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 +
'}';
}
}