# TaiBai
**Repository Path**: yann-up/tai-bai
## Basic Information
- **Project Name**: TaiBai
- **Description**: 一个简单的JAVA的静态工具库
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-04-01
- **Last Updated**: 2026-04-03
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 🗡️ TaiBai SDK (太白)
> **外在如诗般流畅,内在如剑般锋利。**
>
> *Fluent as poetry, sharp as a blade. A modern, fluent, and null-safe utility toolkit for Java 17+.*
[](https://openjdk.java.net/)
[](https://opensource.org/licenses/Apache-2.0)
[]()
## 📜 缘起 (Why TaiBai?)
在 Java 世界里,我们早已习惯了 `StringUtils`、`DateUtils` 等各种大而全的静态工具类。它们像一把把沉重的铁锤,虽然能解决问题,但也带来了无尽的痛点:
- **嵌套地狱**:`StringUtil.camelCase(StringUtil.trim(str))`,代码阅读顺序反人类。
- **上帝类 (God Class)**:动辄几千行的 `Utils` 文件,内部方法极度耦合,难以维护。
- **NPE 陷阱**:无处不在的 `if (str != null)` 判断,让核心业务逻辑被防御性代码淹没。
**TaiBai (太白)** 诞生于对"代码美学"的追求。它全面拥抱 **Java 17+** 的现代语法(Records, Pattern Matching, Sealed Interfaces),采用**门面模式**与**流式 API**,彻底消灭了繁杂的 `Utils` 后缀。
## ✨ 核心心法 (Core Philosophy)
- 🪶 **流式剑法 (Fluent API)**:告别方法嵌套,像写英语长句一样写数据处理逻辑。
- 🛡️ **绝对空安全 (Null-Safe)**:底层 Wrapper 包容一切 `null` 值,链式调用中途遇到 null 自动静默,绝不抛出 `NullPointerException`。
- 🧱 **领域驱动 (DDD & SRP)**:内部按动作与策略拆分(如 `WhitespaceStripper`、`PatternMatcher`),遵循单一职责原则。
- 📦 **零依赖 (Zero-Dependency)**:核心包不引入任何第三方库,极致轻量。
## 🚀 极速起剑 (Quick Start)
### 引入依赖
**Maven**
```xml
io.github.yann-up
taibai-core
0.0.1
```
**Gradle**
```groovy
implementation 'io.github.yann-up:taibai-core:0.0.1'
```
## ⚔️ 招式演示 (Examples)
TaiBai 的一切操作,皆从 `TaiBai.` 这个全局唯一入口开始。所有终端操作提供**双轨制收剑**:
| 收剑方式 | 说明 |
|---|---|
| `.getOrNull()` | 宽容模式,值为 null 时返回 null |
| `.getOrElse(defaultValue)` | 宽容模式,值为 null 时返回默认值 |
| `.getOrThrow()` | 严谨模式,值为 null 时抛出 `TaiBaiException` |
---
### 1. 文本域 `TaiBai.text()`
```java
// 清洗 + 风格转换
String result = TaiBai.text(" user_name_input ")
.trim() // 去除首尾空白(含全角空格)
.toCamelCase() // user_name_input → userNameInput
.getOrElse("default");
// → "userNameInput"
// 支持的大小写转换
TaiBai.text("user_name").toPascalCase().getOrNull(); // → "UserName"
TaiBai.text("userName").toSnakeCase().getOrNull(); // → "user_name"
TaiBai.text("userName").toKebabCase().getOrNull(); // → "user-name"
TaiBai.text("hello").toUpperCase().getOrNull(); // → "HELLO"
// 脱敏处理(金融/隐私场景)
String safePhone = TaiBai.text("+86 138-1234-5678")
.extractNumbers() // → "8613812345678"
.cut(11) // → "13812345678"
.mask(3, 4, '*') // 保留前3后4,中间打码
.getOrThrow(); // 严谨模式:失败则抛出 TaiBaiException
// → "138****5678"
// 填充与截断
TaiBai.text("42").padLeft(5, '0').getOrNull(); // → "00042"
TaiBai.text("Hello, World!").cut(5, "...").getOrNull(); // → "He..."
// 字符串判断(终端操作,直接返回 boolean)
TaiBai.text("hello").contains("ell"); // → true
TaiBai.text("hello").matches("[a-z]+"); // → true
TaiBai.text("hello").equalsToIgnoreCase("HELLO"); // → true
TaiBai.text(" ").isBlank(); // → true
// null 安全:全程静默,不抛 NPE
TaiBai.text(null).trim().toCamelCase().getOrNull(); // → null
```
**文本域中间操作一览:**
`trim()` · `trimLeft()` · `trimRight()` · `removeBlank()` · `toCamelCase()` · `toPascalCase()` · `toSnakeCase()` · `toKebabCase()` · `toUpperCase()` · `toLowerCase()` · `extractNumbers()` · `extractLetters()` · `replace()` · `replaceFirst()` · `cut()` · `padLeft()` · `padRight()` · `mask()` · `format()`
---
### 2. 数字域 `TaiBai.number()`
```java
// 字符串解析 + 运算(解析失败静默,不抛异常)
TaiBai.number("3.14").multiply(2).toDouble(); // → Optional.of(6.28)
TaiBai.number("abc").add(1).getOrNull(); // → null(解析失败静默)
// 四则运算
TaiBai.number(100).add(50).subtract(20).getOrNull(); // → 130
TaiBai.number(10).divide(0).getOrNull(); // → null(除零保护)
// 绝对值 / 取反 / 区间限制
TaiBai.number(-5).abs().getOrNull(); // → 5
TaiBai.number(150).clamp(0, 100).getOrNull(); // → 100
// 格式化(跨域转换为 TextWrapper)
TaiBai.number(1234567.89).format("#,##0.00").getOrNull(); // → "1,234,567.89"
TaiBai.number(1234.56).toCurrency("CNY").getOrNull(); // → "¥1,234.56"
// 类型转换
TaiBai.number("42").toInt(); // → Optional.of(42)
TaiBai.number("3.14").toBigDecimal(); // → Optional.of(3.14)
// 范围判断
TaiBai.number(50).isInRange(0, 100); // → true
```
---
### 3. 时间域 `TaiBai.time()`
```java
// 当前时间操作
String expireTime = TaiBai.time()
.plusDays(3)
.atEndOfDay()
.format("yyyy-MM-dd HH:mm:ss");
// → "2026-04-05 23:59:59"
// 多种入参方式
TaiBai.time(someLocalDateTime); // LocalDateTime
TaiBai.time(new Date()); // java.util.Date 自动转换
TaiBai.time("2026-01-01", "yyyy-MM-dd"); // 字符串解析
// 时间加减
TaiBai.time().plusMonths(1).plusHours(8).format("yyyy-MM-dd HH:mm:ss");
TaiBai.time().minusDays(7).atStartOfDay().format("yyyy-MM-dd HH:mm:ss");
// 边界截断
TaiBai.time().atStartOfMonth().format("yyyy-MM-dd"); // 当月第一天 00:00:00
TaiBai.time().atEndOfMonth().format("yyyy-MM-dd"); // 当月最后一天 23:59:59
// 比较判断
TaiBai.time(someDate).isBefore(LocalDateTime.now()); // → true/false
TaiBai.time(someDate).isBetween(start, end); // → true/false
// 时间戳
TaiBai.time().toEpochMilli(); // → 毫秒时间戳
// null 安全
TaiBai.time(null, "yyyy-MM-dd").plusDays(1).getOrNull(); // → null(静默传播)
```
---
### 4. 集合域 `TaiBai.list()`
```java
// 过滤 + 排序 + 转换
List result = TaiBai.list(List.of("banana", "apple", "cherry"))
.filter(s -> s.length() > 5)
.sorted()
.toList();
// → ["banana", "cherry"]
// 映射 + 去重 + 限制
TaiBai.list(List.of(1, 2, 2, 3, 3, 4))
.distinct()
.map(n -> n * 2)
.limit(3)
.toList();
// → [2, 4, 6]
// 聚合操作
TaiBai.list(List.of(1, 2, 3)).count(); // → 3
TaiBai.list(List.of(1, 2, 3)).first(); // → Optional.of(1)
TaiBai.list(List.of(1, 2, 3)).any(n -> n > 2); // → true
TaiBai.list(List.of(1, 2, 3)).all(n -> n > 0); // → true
// 分组
Map> grouped = TaiBai.list(List.of("a", "bb", "cc", "ddd"))
.groupBy(String::length);
// → {1: ["a"], 2: ["bb", "cc"], 3: ["ddd"]}
// 跨域转换为 TextWrapper
TaiBai.list(List.of("Java", "17", "rocks")).join(", ").getOrNull();
// → "Java, 17, rocks"
// null 安全:null 集合视为空集合
TaiBai.list(null).filter(x -> true).toList(); // → []
```
---
### 5. 编解码域 `TaiBai.codec()`
```java
// Base64 编解码
TaiBai.codec("hello").encodeBase64().getOrNull(); // → "aGVsbG8="
TaiBai.codec("aGVsbG8=").decodeBase64().getOrNull(); // → "hello"
// Base64 往返
TaiBai.codec("hello").encodeBase64().decodeBase64().getOrNull(); // → "hello"
// URL 编解码
TaiBai.codec("hello world").encodeUrl().getOrNull(); // → "hello+world"
TaiBai.codec("hello+world").decodeUrl().getOrNull(); // → "hello world"
// 哈希摘要(单向,不可逆)
TaiBai.codec("hello").md5().getOrNull(); // → "5d41402abc4b2a76b9719d911017c592"
TaiBai.codec("hello").sha256().getOrNull(); // → "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
// null 安全
TaiBai.codec(null).encodeBase64().getOrNull(); // → null(静默传播)
```
## 🏗️ 内部架构 (Architecture)
TaiBai 采用**"外在门面 + 内核策略"**的双层架构设计:
```
TaiBai (唯一入口门面)
├── text() → TextWrapper (sealed interface)
│ └── TextWrapperImpl
│ ├── WhitespaceStripper # 空白处理
│ ├── CaseConverter # 大小写转换
│ ├── StringCutter # 截断填充
│ ├── MaskProcessor # 脱敏处理
│ └── PatternMatcher # 正则匹配
├── number() → NumberWrapper (sealed interface)
│ └── NumberWrapperImpl
│ ├── ArithmeticProcessor # 四则运算
│ ├── NumberParser # 字符串解析
│ └── NumberFormatter # 格式化输出
├── time() → TimeWrapper (sealed interface)
│ └── TimeWrapperImpl
│ ├── TimeParser # 时间解析
│ ├── TimeCalculator # 时间加减
│ └── TimeFormatter # 格式化输出
├── list() → CollectionWrapper (sealed interface)
│ └── CollectionWrapperImpl # Stream 封装
└── codec() → CodecWrapper (sealed interface)
└── CodecWrapperImpl
├── Base64Codec # Base64 编解码
├── UrlCodec # URL 编解码
└── HashProcessor # MD5/SHA-256
```
**核心设计约束:**
1. **入口收敛**:新增功能统一挂载在 `TaiBai` 门面及对应的 Wrapper 接口下。
2. **拒绝 Utils**:内部实现类必须以动作命名(`xxxProcessor`、`xxxFormatter`、`xxxParser`),严禁创建 God Class。
3. **拥抱 Java 17**:使用 `sealed interface` 控制实现边界,使用 `record` 作为数据载体,使用 `switch` 模式匹配简化逻辑分支。
4. **不可变 Wrapper**:所有中间操作返回新的 Wrapper 实例,保证线程安全。
## 🤝 共建 (Contributing)
欢迎提交 Issue 和 Pull Request,让我们一起锻造这把 Java 界的青莲宝剑。
## 📄 开源协议 (License)
TaiBai SDK is released under the [Apache 2.0 License](https://opensource.org/licenses/Apache-2.0).