1. 简介
Cactoos 是一个面向对象风格的 Java 基元类型库,它的设计哲学是“一切皆对象”,避免使用静态工具类和过程式编程惯用法。
本文将带你了解 Cactoos 提供的一些核心类,帮助你在项目中更优雅地处理字符串、集合等常见操作。✅
⚠️ 注意:Cactoos 并不是为了替代 Guava 或 Apache Commons,而是提供一种更符合 OOP 和函数式风格的编程方式。
2. Cactoos 核心理念
Cactoos 覆盖了从字符串处理到数据结构、IO、日期时间等多个领域。它提供的功能与 Guava 和 Apache Commons 类似,但更强调面向对象设计原则(如 SOLID),尤其是:
- 消除
null
- 避免副作用
- 所有操作都是不可变的(immutable)
- 使用组合而非继承
2.1 与 Apache Commons 的对比
Cactoos 用“对象”替代了 Apache Commons 中常见的“静态方法”。这种转变让代码更具可读性和可测试性。
下面是 StringUtils
中常用静态方法与 Cactoos 对应类的对照表:
StringUtils 静态方法 | Cactoos 等价类 |
---|---|
isBlank() |
IsBlank |
lowerCase() |
Lowered |
upperCase() |
Upper |
rotate() |
Rotated |
swapCase() |
SwappedCase |
stripStart() |
TrimmedLeft |
stripEnd() |
TrimmedRight |
📌 官方文档中有更完整的对照表:Our Objects vs Their Static Methods
接下来我们通过实际代码看看这些类怎么用。
3. Maven 依赖
使用前先引入依赖。最新版本可在 Maven Central 查询:
<dependency>
<groupId>org.cactoos</groupId>
<artifactId>cactoos</artifactId>
<version>0.55.0</version>
</dependency>
✅ 推荐使用较新版本,避免已知 bug。
4. 字符串操作
Cactoos 提供了丰富的字符串处理类,全部基于 Text
接口。
4.1 创建字符串对象
使用 TextOf
包装原始字符串:
String testString = new TextOf("Test String").asString();
💡
TextOf
是最基础的文本包装类,几乎所有字符串操作都基于它。
4.2 格式化字符串
用 FormattedText
实现 String.format
的功能:
String formattedString = new FormattedText("Hello %s", stringToFormat).asString();
测试示例:
StringMethods obj = new StringMethods();
String formattedString = obj.createdFormattedString("John");
assertEquals("Hello John", formattedString);
4.3 转换大小写
- 转小写:
Lowered
- 转大写:
Upper
String lowerCaseString = new Lowered(new TextOf(testString)).asString();
String upperCaseString = new Upper(new TextOf(testString)).asString();
验证示例:
StringMethods obj = new StringMethods();
String lowerCaseString = obj.toLowerCase("TeSt StrIng");
String upperCaseString = obj.toUpperCase("TeSt StrIng");
assertEquals("test string", lowerCaseString);
assertEquals("TEST STRING", upperCaseString);
✅ 这种链式写法虽然略 verbose,但好处是类型安全、易于 mock 和测试。
4.4 判断空字符串
使用 IsBlank
替代 StringUtils.isBlank()
:
boolean isBlank = new IsBlank(new TextOf(testString)).value();
⚠️ 注意:IsBlank
返回的是 Scalar<Boolean>
,需要调用 .value()
获取实际值。
正确写法应该是:
assertTrue(new IsBlank(new TextOf("")).value());
assertFalse(new IsBlank(new TextOf("hello")).value());
5. 集合操作
Cactoos 对集合的操作也完全对象化,避免使用 for
循环或 Stream
的副作用。
5.1 遍历集合
使用 And
+ Mapped
实现无副作用的遍历(类似 forEach
):
new And(
new Mapped<>(
new FuncOf<>(
input -> System.out.printf("Item: %s\n", input),
new True()
),
strings
)
).value();
❌ 踩坑提醒:
And
通常用于布尔组合,这里用于副作用操作其实有点“歪楼”,但确实能跑通。更推荐使用IoCheckedProc
或自定义Proc
。
5.2 过滤集合
使用 Filtered
对集合进行过滤:
public Collection<String> getFilteredList(List<String> strings) {
return new ListOf<>(
new Filtered<>(
s -> s.length() == 5,
strings
)
);
}
测试用例:
CollectionUtils obj = new CollectionUtils();
List<String> strings = new ArrayList<>();
strings.add("Hello");
strings.add("John");
strings.add("Smith");
strings.add("Eric");
strings.add("Dizzy");
int size = obj.getFilteredList(strings).size();
assertEquals(3, size);
✅ 匹配项为:"Hello"、"Smith"、"Dizzy"
更多集合相关类可参考官方文档:Iterables/Collections/Lists/Sets
6. 总结
Cactoos 提供了一种完全对象化的 Java 编程方式,适用于追求高可读性、低副作用、强可测性的项目。
除了本文介绍的字符串和集合操作,它还支持:
- ✅ IO 操作:
Input
、Output
、Bytes
、Text
等 - ✅ 日期时间:
Now
、Age
、Elapsed
等 - ✅ 并发:
SyncScalar
、IoCheckedScalar
等
📌 适用场景:
- 团队强调函数式 + OOP 风格
- 想减少
null
和静态工具类滥用- 需要高度可测试的代码
⚠️ 注意事项:
- 性能开销略高(对象创建频繁)
- 学习曲线较陡,团队需统一认知
- 社区活跃度不如 Guava
所有示例代码已托管至 GitHub:https://github.com/tech-tutorial/tutorials/tree/master/libraries-data-3