基本工具
-
- 7、文本拆分器(Splitter)
- 8、字符串连接器(Joiner)
- 9、字符匹配与清洗器(CharMatcher)
- 10、命名规范转换(CaseFormat)
- 11、字符串处理(Strings)
- 12、其它工具
-
- 12.1、Converter(双向类型转换器)
- [12.2、Ascii(ASCII 字符处理)](#12.2、Ascii(ASCII 字符处理))
- 12.3、Enums(枚举工具类)
- [12.4、Functions 工具扩展](#12.4、Functions 工具扩展)
- [12.5、Predicates 条件谓词扩展](#12.5、Predicates 条件谓词扩展)
- [12.6、Suppliers 供应商扩展](#12.6、Suppliers 供应商扩展)
- 13、常见替代方案与演进关系 (Java 8+ vs Guava)
7、文本拆分器(Splitter)
com.google.common.base.Splitter 是 Guava 提供的字符串拆分工具。相比 JDK 原生的 String.split(),它解决了 忽略空字符串、修剪空格(trim) 以及 流式延迟计算 等常见痛点,且不会静默丢弃末尾的空字符串。
7.1、核心API
工厂构造方法(指定拆分规则)
| 工厂方法 | 说明 | 示例 |
|---|---|---|
Splitter.on(char) |
按指定单个字符拆分 | Splitter.on(',') |
Splitter.on(String) |
按固定字符串拆分 | Splitter.on("", "") |
Splitter.on(CharMatcher) |
按字符匹配器拆分 | Splitter.on(CharMatcher.whitespace()) |
Splitter.on(Pattern) |
按正则表达式拆分 | Splitter.on(Pattern.compile(""\\d+"")) |
Splitter.onPattern(String) |
按正则表达式字符串拆分 | Splitter.onPattern(""\\s+"") |
Splitter.fixedLength(int) |
按固定字符长度等分` | Splitter.fixedLength(3) |
链式修饰方法(配置处理逻辑)
Splitter 实例是不可变的(Immutable),修饰方法会返回一个新的 Splitter 实例。
| 修饰方法 | 说明 |
|---|---|
omitEmptyStrings() |
自动过滤拆分后产生的空字符串 "" |
trimResults() |
对拆分后的每个元素执行 trim() 去除前后空白 |
trimResults(CharMatcher) |
对拆分后的每个元素去除匹配到的特定字符 |
limit(int) |
限制最大拆分份数(达到 limit 数量后,剩余部分不再拆分) |
终止方法(执行拆分并返回)
| 终止方法 | 返回类型 | 说明 |
|---|---|---|
split(CharSequence) |
Iterable<String> |
默认延迟计算,遍历时才真正执行拆分 |
splitToList(CharSequence) |
List<String> |
立即执行拆分并返回不可变 List(Java 8+ 常用) |
splitToStream(CharSequence) |
Stream<String> |
转换为 Java Stream 流(Guava 28.2+ 支持) |
withKeyValueSeparator(...) |
MapSplitter |
进一步配置,用于将字符串直接拆分为 Map |
7.2、使用示例
java
import com.google.common.base.CharMatcher;
import com.google.common.base.Splitter;
import java.util.List;
import java.util.Map;
public class SplitterDetailExample {
public static void main(String[] args) {
// 1. 基础拆分与空白处理 (omitEmptyStrings + trimResults)
String input1 = " apple , , banana, orange , ";
List<String> list1 = Splitter.on(',')
.trimResults() // 去除每个元素的前后空格
.omitEmptyStrings() // 忽略空字符串
.splitToList(input1);
System.out.println("示例 1: " + list1);
// 输出: [apple, banana, orange]
// 2. 限制拆分份数 (limit)
String input2 = "a,b,c,d,e";
List<String> list2 = Splitter.on(',')
.limit(3) // 最多拆分为 3 份,剩余部分保持原样
.splitToList(input2);
System.out.println("示例 2: " + list2);
// 输出: [a, b, c,d,e]
// 3. 按固定长度拆分 (fixedLength)
String input3 = "12345678";
List<String> list3 = Splitter.fixedLength(3)
.splitToList(input3);
System.out.println("示例 3: " + list3);
// 输出: [123, 456, 78]
// 4. 按正则/字符匹配器拆分 (onPattern / CharMatcher)
String input4 = "foo123bar456baz";
List<String> list4 = Splitter.onPattern("\\d+")
.splitToList(input4);
System.out.println("示例 4: " + list4);
// 输出: [foo, bar, baz]
// 5. 拆分为 Map (withKeyValueSeparator)
String input5 = "name=Alice; age=25; city=Beijing";
Map<String, String> map = Splitter.on(';')
.trimResults()
.withKeyValueSeparator('=') // 指定键值对分隔符
.split(input5);
System.out.println("示例 5: " + map);
// 输出: {name=Alice, age=25, city=Beijing}
}
}
java
示例 1: [apple, banana, orange]
示例 2: [a, b, c,d,e]
示例 3: [123, 456, 78]
示例 4: [foo, bar, baz]
示例 5: {name=Alice, age=25, city=Beijing}
8、字符串连接器(Joiner)
com.google.common.base.Joiner 是 Guava 提供的字符串拼接工具。与 JDK 8+ 的 String.join() 或 StringJoiner 相比,Guava 的 Joiner 提供了对 null 值的安全处理(忽略或替换)、数组/集合/迭代器的直接拼接以及 Map 映射关系的优雅格式化。
8.1、核心API
工厂构造方法(指定连接符)
| 工厂方法 | 说明 | 示例 |
|---|---|---|
Joiner.on(String) |
使用指定的字符串作为分隔符 | Joiner.on(", ") |
Joiner.on(char) |
使用指定的字符作为分隔符 | Joiner.on('-') |
链式配置方法(处理 null 与扩展配置)
Joiner 实例是 不可变(Immutable)且线程安全 的,所有配置方法都会返回一个新的 Joiner 实例。
| 配置方法 | 说明 |
|---|---|
skipNulls() |
拼接时自动跳过/忽略为 null 的元素 |
useForNull(String) |
拼接时将为 null 的元素替换为指定的字符串 |
withKeyValueSeparator(String/char) |
指定键值对之间的分隔符,返回 MapJoiner,用于拼接 Map |
注意:skipNulls() 和 useForNull() 是互斥的,不能同时调用。如果都不配置,拼接包含 null 的序列时会抛出 NullPointerException。
终止方法(执行拼接并返回)
-
普通 Joiner 的终止方法
终止方法 返回/操作 说明 join(Iterable/Iterator/Object[])String 拼接集合、迭代器或数组中的元素 join(Object, Object, Object...)String拼接离散传入的多个对象 appendTo(A, ...)A(追加目标),将结果直接追加到 StringBuilder、Writer 或 Appendable 中 -
MapJoiner 的终止方法
通过 Joiner.on(...).withKeyValueSeparator(...) 构建后使用:
终止方法 返回/操作 说明 join(Map<?, ?>)String将 Map 拼接为形如 k1=v1&k2=v2 的字符串 appendTo(A, Map<?, ?>)A(追加目标),将 Map 拼接结果追加到 Appendable 目标对象中
8.2、使用示例
java
import com.google.common.base.Joiner;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class JoinerDetailExample {
public static void main(String[] args) throws IOException {
// 包含 null 元素的测试列表
List<String> listWithNull = Arrays.asList("Apple", null, "Banana", "Orange", null);
// 1. 跳过 null 元素 (skipNulls)
String skipNullsResult = Joiner.on(", ")
.skipNulls()
.join(listWithNull);
System.out.println("示例 1 (skipNulls): " + skipNullsResult);
// 输出: Apple, Banana, Orange
// 2. 将 null 替换为指定默认值 (useForNull)
String useForNullResult = Joiner.on(" | ")
.useForNull("N/A")
.join(listWithNull);
System.out.println("示例 2 (useForNull): " + useForNullResult);
// 输出: Apple | N/A | Banana | Orange | N/A
// 3. 追加到现有的 StringBuilder 或 Appendable (appendTo)
StringBuilder builder = new StringBuilder("Selected fruits: ");
Joiner.on(" + ")
.skipNulls()
.appendTo(builder, listWithNull);
System.out.println("示例 3 (appendTo): " + builder.toString());
// 输出: Selected fruits: Apple + Banana + Orange
// 4. Map 拼接 (withKeyValueSeparator)
Map<String, String> queryParams = new HashMap<>();
queryParams.put("search", "guava");
queryParams.put("page", "1");
queryParams.put("lang", "zh");
String queryString = Joiner.on("&")
.withKeyValueSeparator("=")
.join(queryParams);
System.out.println("示例 4 (MapJoiner): " + queryString);
// 输出: search=guava&page=1&lang=zh
// 5. 拼接变长参数 / 离散对象
String discreteResult = Joiner.on("-").useForNull("0").join("ID", 101, null, "ACTIVE");
System.out.println("示例 5 (离散对象): " + discreteResult);
// 输出: ID-101-0-ACTIVE
}
}
java
示例 1 (skipNulls): Apple, Banana, Orange
示例 2 (useForNull): Apple | N/A | Banana | Orange | N/A
示例 3 (appendTo): Selected fruits: Apple + Banana + Orange
示例 4 (MapJoiner): search=guava&page=1&lang=zh
示例 5 (离散对象): ID-101-0-ACTIVE
9、字符匹配与清洗器(CharMatcher)
com.google.common.base.CharMatcher 是 Guava 提供的字符匹配与判定工具。它将字符判定逻辑与字符串操作(过滤、保留、替换、修剪、计数等)完美解耦,相比正则表达式性能更高,且代码表达力极强。
9.1、核心API
9.1、常量与工厂方法(创建匹配器)
1. 预定义常量匹配器
| 常量/方法 | 匹配内容 |
|---|---|
CharMatcher.none() |
不匹配任何字符 |
CharMatcher.any() |
匹配任意字符 |
CharMatcher.whitespace() |
匹配所有空白字符(空格、换行、制表符等) |
CharMatcher.ascii() |
匹配所有 ASCII 字符 (0x00 - 0x7F) |
CharMatcher.javaDigit() |
匹配 Java 语言定义的数字字符 |
CharMatcher.javaLetter() |
匹配 Java 语言定义的字母字符 |
CharMatcher.javaLetterOrDigit() |
匹配 Java 语言定义的字母或数字 |
CharMatcher.breakingWhitespace() |
匹配可换行的空白字符 |
2. 自定义工厂方法
| 工厂方法 | 说明 | 示例 |
|---|---|---|
CharMatcher.is(char) |
匹配指定字符 | CharMatcher.is('a') |
CharMatcher.isNot(char) |
匹配非指定字符 | CharMatcher.isNot('a') |
CharMatcher.anyOf(CharSequence) |
匹配给定字符集中的任意字符 | CharMatcher.anyOf("aeiou") |
CharMatcher.noneOf(CharSequence) |
不匹配给定字符集中的任何字符 | CharMatcher.noneOf("123") |
CharMatcher.inRange(char, char) |
匹配指定字符范围内的字符 | CharMatcher.inRange('a', 'z') |
CharMatcher.forPredicate(Predicate) |
使用自定义断言创建匹配器 | CharMatcher.forPredicate(c -> ...) |
9.1.2、组合方法(逻辑运算)
CharMatcher 实例可以像布尔逻辑一样进行组合,构建复杂的匹配规则。
| 组合方法 | 说明 | 示例 |
|---|---|---|
negate() |
取反(逻辑非) | CharMatcher.is('a').negate() |
and(CharMatcher) |
取交集(逻辑与) | matcher1.and(matcher2) |
or(CharMatcher) |
取并集(逻辑或) | matcher1.or(matcher2) |
9.1.3、操作方法(对字符串进行处理)
1. 判定与检索
| 方法 | 返回类型 | 说明 |
|---|---|---|
matchesAnyOf(CharSequence) |
boolean | 序列中是否包含至少一个匹配字符 |
matchesAllOf(CharSequence) |
boolean | 序列中的字符是否全部匹配 |
matchesNoneOf(CharSequence) |
boolean | 序列中是否完全不包含匹配字符 |
countIn(CharSequence) |
int | 统计匹配字符的数量 |
indexIn(CharSequence) |
int | 返回第一个匹配字符的索引(未找到返回 -1) |
indexIn(CharSequence, int) |
int | 从指定位置开始查找第一个匹配字符的索引 |
2. 移除与留存
| 方法 | 返回类型 | 说明 |
|---|---|---|
removeFrom(CharSequence) |
String | 移除所有匹配的字符 |
retainFrom(CharSequence) |
String | 仅保留所有匹配的字符 |
3. 替换与折叠
| 方法 | 返回类型 | 说明 |
|---|---|---|
replaceFrom(CharSequence, char) |
String | 将所有匹配字符替换为指定字符 |
replaceFrom(CharSequence, CharSequence) |
String | 将所有匹配字符替换为指定字符串 |
collapseFrom(CharSequence, char) |
String | 将连续匹配的字符序列压缩替换为单个字符 |
trimAndCollapseFrom(CharSequence, char) |
String | 先执行 trimFrom,再执行 collapseFrom |
4. 修剪(Trim)
| 方法 | 返回类型 | 说明 |
|---|---|---|
trimFrom(CharSequence) |
String | 移除首尾匹配的字符 |
trimLeadingFrom(CharSequence) |
String | 仅移除头部匹配的字符 |
trimTrailingFrom(CharSequence) |
String | 仅移除尾部匹配的字符 |
9.2、使用示例
java
import com.google.common.base.CharMatcher;
public class CharMatcherDetailExample {
public static void main(String[] args) {
// 1. 提纯/仅保留数字 (retainFrom)
String phoneInput = "+86 138-1234-5678 (Mobile)";
String digitsOnly = CharMatcher.javaDigit().retainFrom(phoneInput);
System.out.println("示例 1 (提纯数字): " + digitsOnly);
// 输出: 8613812345678
// 2. 移除指定字符 (removeFrom)
String rawText = "Hello, World! #2026";
// 移除标点符号或特定符号
String cleanText = CharMatcher.anyOf(",!#").removeFrom(rawText);
System.out.println("示例 2 (移除特定符号): " + cleanText);
// 输出: Hello World 2026
// 3. 规整连续空格 (collapseFrom & trimAndCollapseFrom)
String messySpacing = " Guava CharMatcher is awesome! ";
// 将连续的空格压缩为一个空格,并去掉首尾空格
String normalized = CharMatcher.whitespace().trimAndCollapseFrom(messySpacing, ' ');
System.out.println("示例 3 (压缩连续空格): " + normalized);
// 输出: Guava CharMatcher is awesome!
// 4. 组合匹配器 (or / inRange)
// 匹配所有小写英文字母及数字
CharMatcher lowerOrDigit = CharMatcher.inRange('a', 'z').or(CharMatcher.javaDigit());
String mixedStr = "ABC-abc-123-XYZ";
String retainedLowerAndDigit = lowerOrDigit.retainFrom(mixedStr);
System.out.println("示例 4 (组合匹配): " + retainedLowerAndDigit);
// 输出: abc123
// 5. 字符计数与判定 (countIn / matchesAllOf)
String passwordCandidate = "123456";
int digitCount = CharMatcher.javaDigit().countIn(passwordCandidate);
boolean isPureDigits = CharMatcher.javaDigit().matchesAllOf(passwordCandidate);
System.out.println("示例 5 (计数与纯数字检查): 数字个数=" + digitCount + ", 是否全为数字=" + isPureDigits);
// 输出: 数字个数=6, 是否全为数字=true
// 6. 敏感信息脱敏/掩码 (replaceFrom)
String cardNum = "4532-7512-8899-1234";
// 将连字符以外的数字部分模糊化处理
String masked = CharMatcher.javaDigit().replaceFrom(cardNum, '*');
System.out.println("示例 6 (掩码替换): " + masked);
// 输出: ****-****-****-****
}
}
java
示例 1 (提纯数字): 8613812345678
示例 2 (移除特定符号): Hello World 2026
示例 3 (压缩连续空格): Guava CharMatcher is awesome!
示例 4 (组合匹配): abc123
示例 5 (计数与纯数字检查): 数字个数=6, 是否全为数字=true
示例 6 (掩码替换): ****-****-****-****
10、命名规范转换(CaseFormat)
com.google.common.base.CaseFormat 是 Guava 提供的枚举类,用于在不同的命名规范(如驼峰命名、下划线命名、短横线分隔等)之间快速转换字符串。
CaseFormat 枚举常量
| 常量名 | 示例格式 | 说明 / 常见别名 |
|---|---|---|
LOWER_HYPHEN |
test-variable |
小写短横线分隔(Kebab-case) |
LOWER_UNDERSCORE |
test_variable |
小写下划线分隔(Snake-case) |
LOWER_CAMEL |
testVariable |
小驼峰命名(lowerCamelCase) |
UPPER_CAMEL |
TestVariable |
大驼峰命名(PascalCase) |
UPPER_UNDERSCORE |
TEST_VARIABLE |
大写下划线分隔(常量命名规范) |
10.1、核心API
| 方法签名 | 说明 |
|---|---|
to(CaseFormat targetFormat, String str) |
将符合当前 CaseFormat 格式的字符串 str 转换为目标 targetFormat 格式 |
converterTo(CaseFormat targetFormat) |
返回一个 Converter<String, String> 转换器实例,支持双向转换与函数式复用 |
10.2、使用示例
1. 直接转换格式(to 方法)
java
import com.google.common.base.CaseFormat;
public class CaseFormatExample {
public static void main(String[] args) {
// 蛇形 (lower_underscore) -> 小驼峰 (lowerCamel)
String camelResult = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, "user_first_name");
System.out.println(camelResult); // 输出: userFirstName
// 蛇形 (lower_underscore) -> 大驼峰 (UpperCamel)
String pascalResult = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, "user_first_name");
System.out.println(pascalResult); // 输出: UserFirstName
// 小驼峰 (lowerCamel) -> 短横线 (lower-hyphen)
String kebabResult = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, "orderDetailId");
System.out.println(kebabResult); // 输出: order-detail-id
// 小驼峰 (lowerCamel) -> 常量格式 (UPPER_UNDERSCORE)
String constResult = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, "maxRetryCount");
System.out.println(constResult); // 输出: MAX_RETRY_COUNT
}
}
java
userFirstName
UserFirstName
order-detail-id
MAX_RETRY_COUNT
2. 使用转换器(converterTo 方法)
适用于需要重复使用同一种转换逻辑或配合流式 API 进行批量处理的场景:
java
import com.google.common.base.CaseFormat;
import com.google.common.base.Converter;
public class ConverterExample {
public static void main(String[] args) {
// 创建"下划线转小驼峰"的转换器对象
Converter<String, String> underscoreToCamel =
CaseFormat.LOWER_UNDERSCORE.converterTo(CaseFormat.LOWER_CAMEL);
// 正向转换:下划线 -> 小驼峰
String camel = underscoreToCamel.convert("create_time");
System.out.println(camel); // 输出: createTime
// 反向转换:小驼峰 -> 下划线
String underscore = underscoreToCamel.reverse().convert("updateTime");
System.out.println(underscore); // 输出: update_time
}
}
java
createTime
update_time
11、字符串处理(Strings)
com.google.common.base.Strings 是 Guava 提供的轻量级字符串处理工具类,主要用来简化 null / 空字符串的判断与转换、固定长度填充、重复拼接以及前缀后缀比对等常见操作。
11.1、核心API
| 方法名 | 说明 |
|---|---|
isNullOrEmpty(String string) |
判断字符串是否为 null 或空字符串 "" |
nullToEmpty(String string) |
若为 null 则转换为 "",否则返回原值 |
emptyToNull(String string) |
若为空字符串 "" 则转换为 null,否则返回原值 |
padStart(String string, int minLength, char padChar) |
前缀填充:若长度小于 minLength,在开头补齐 padChar |
padEnd(String string, int minLength, char padChar) |
后缀填充:若长度小于 minLength,在结尾补齐 padChar |
repeat(String string, int count) |
重复拼接原字符串 count 次 |
commonPrefix(CharSequence a, CharSequence b) |
获取两字符串的最长公共前缀 |
commonSuffix(CharSequence a, CharSequence b) |
获取两字符串的最长公共后缀 |
lenientFormat(String template, Object... args) |
宽容格式化:类似 String.format 但参数缺失或异常时绝不抛出 Exception |
11.2、使用示例
java
import com.google.common.base.Strings;
public class StringsExample {
public static void main(String[] args) {
// 1. null 与空字符串转换 & 判断
System.out.println(Strings.isNullOrEmpty(null)); // true
System.out.println(Strings.isNullOrEmpty("")); // true
System.out.println(Strings.isNullOrEmpty(" ")); // false(注意:空白字符不视为空)
System.out.println(Strings.nullToEmpty(null)); // ""
System.out.println(Strings.emptyToNull("")); // null
// 2. 字符串填充 (常用于生成固定位数的订单号/流水号)
System.out.println(Strings.padStart("42", 5, '0')); // "00042"
System.out.println(Strings.padEnd("API", 6, '!')); // "API!!!"
System.out.println(Strings.padStart("123456", 4, '0'));// "123456" (超长时保持原样)
// 3. 字符串重复
System.out.println(Strings.repeat("=-", 5)); // "=-=-=-=-=-"
// 4. 公共前缀与后缀提取
String path1 = "/usr/local/bin/java";
String path2 = "/usr/local/etc/nginx";
System.out.println(Strings.commonPrefix(path1, path2)); // "/usr/local/"
String file1 = "UserServiceTest.java";
String file2 = "OrderServiceTest.java";
System.out.println(Strings.commonSuffix(file1, file2)); // "ServiceTest.java"
// 5. 宽容格式化 (常用于日志打印,即使参数数量对不上也不会报错)
String formatted = Strings.lenientFormat("User %s logged in at %s", "Alice");
System.out.println(formatted); // "User Alice logged in at %s [1 unverified arg]"
}
}
java
true
true
false
null
00042
API!!!
123456
=-=-=-=-=-
/usr/local/
erServiceTest.java
User Alice logged in at %s
12、其它工具
12.1、Converter(双向类型转换器)
- 用于定义双向的类型转换逻辑,继承自 Function,不仅支持前向转换(convert(A)),还支持通过 .reverse() 自动获取反向转换器。
- 常见内置实现如 Ints.stringConverter(),可实现字符串与 Integer 之间的双向安全互转。
12.2、Ascii(ASCII 字符处理)
- 专门针对 ASCII 字符及字符串的高性能大小写转换与判定。
- 它不受 JVM 本地化环境(Locale)的影响,执行效率显著高于 JDK 标准的 String.toLowerCase() 或 Character 方法。
- 核心 API:Ascii.toLowerCase(str)、Ascii.toUpperCase(str)、Ascii.isLowerCase©。
12.3、Enums(枚举工具类)
- 用于安全地操作枚举类型,避免直接使用 Enum.valueOf() 时因找不到枚举常量而抛出 IllegalArgumentException。
- 核心 API:Enums.getIfPresent(MyEnum.class, "VALUE") 会返回一个 Optional,若枚举值不存在则优雅返回空,极适合解析外部传入的配置或前端参数。
12.4、Functions 工具扩展
- Functions.identity():返回输入对象本身的恒等函数。
- Functions.forMap(Map<K, V> map):将一个普通的 Map 包装为 Function 接口,常用于集合转换映射。
- Functions.compose(f, g):组合两个函数,实现链式调用。
12.5、Predicates 条件谓词扩展
- Predicates.instanceOf(Class<?> type):判断对象是否为指定类型的实例。
- Predicates.in(Collection<?> target):判断元素是否存在于指定集合中(类似于 SQL 的 IN 操作)。
- Predicates.notNull():快速过滤所有非空元素的断言。
12.6、Suppliers 供应商扩展
- Suppliers.memoize(Supplier delegate):将一个耗时的 Supplier 包装为线程安全的单次缓存(第一次调用时计算并保存结果,后续直接复用)。
- Suppliers.memoizeWithExpiration(Supplier delegate, long duration, TimeUnit unit):支持带过期时间的缓存 Supplier,在多线程环境下到期后会自动重新触发计算。
13、常见替代方案与演进关系 (Java 8+ vs Guava)
随着 JDK 的升级,部分 Guava 基础工具已有原生实现,选型对照如下:
| Guava 工具 | JDK 推荐替代方案 | 建议 |
|---|---|---|
Objects.equal(a, b) |
java.util.Objects.equals(a, b) |
优先使用 JDK |
Objects.hashCode(a, b) |
java.util.Objects.hash(a, b) |
优先使用 JDK |
com.google.common.base.Optional |
java.util.Optional |
优先使用 JDK(注意两者类不兼容) |
Ordering |
java.util.Comparator (如 Comparator.comparing(...).thenComparing(...)) |
简单排序用 JDK,复杂极值查找(leastOf/greatestOf)继续用 Guava |
Preconditions |
java.util.Objects.requireNonNull |
非空校验可用 JDK,复杂条件与状态校验继续用 Guava |