为了方便我们对字符串的处理,Guava给我们提供了好多很方便的工具类,接下来我们对Guava里面字符串相关的帮助类做一个简单的介绍。
一 连接器 -- Joiner
Joiner用于帮助我们把多个字符串通过连接符连接起来。Joiner里面也提供和很多很有用的方法,比如null提花,跳过null值等等。而且还派生了MapJoiner类用于连接多个Map,可以同时制定Map之间的连接符和key value之间的连接符。
1.1 Joiner方法介绍
public class Joiner {
/**
* 创建连接器 Joiner
* @param separator 连接符
*/
public static Joiner on(String separator);
/**
* 创建连接器 Joiner
* @param separator 连接符
*/
public static Joiner on(char separator);
/**
* 相当于parts中间添加appendable
* StringBuffer也是一个Appendable
*/
@CanIgnoreReturnValue
public <A extends Appendable> A appendTo(A appendable, Iterable<?> parts) throws IOException;
/**
* 相当于parts中的每个元素都转换为String,然后在每个元素的中间添加appendable
* StringBuffer也是一个Appendable
*/
@CanIgnoreReturnValue
public <A extends Appendable> A appendTo(A appendable, Iterator<?> parts) throws IOException;
/**
* 相当于parts中的每个元素都转换为String,然后在每个元素的中间添加appendable
* StringBuffer也是一个Appendable
*/
@CanIgnoreReturnValue
public final <A extends Appendable> A appendTo(A appendable, Object[] parts) throws IOException;
/**
* 把元素转换为String,然后在每个元素的中间添加appendable
*/
@CanIgnoreReturnValue
public final <A extends Appendable> A appendTo(
A appendable, @Nullable Object first, @Nullable Object second, Object... rest)
throws IOException;
/**
* 相当于parts中的每个元素都转换为String,然后在每个元素的中间添加builder.toString()
*/
@CanIgnoreReturnValue
public final StringBuilder appendTo(StringBuilder builder, Iterable<?> parts);
/**
* 相当于parts中的每个元素都转换为String,然后在每个元素的中间添加builder.toString()
*/
@CanIgnoreReturnValue
public final StringBuilder appendTo(StringBuilder builder, Iterator<?> parts);
/**
* 相当于parts中的每个元素都转换为String,然后在每个元素的中间添加builder.toString()
*/
@CanIgnoreReturnValue
public final StringBuilder appendTo(StringBuilder builder, Object[] parts);
/**
* 相当于每个元素都转换为String,然后在每个元素的中间添加builder.toString()
*/
@CanIgnoreReturnValue
public final StringBuilder appendTo(
StringBuilder builder, @Nullable Object first, @Nullable Object second, Object... rest);
/**
* 把parts每个元素转换为字符串,再添加连接符之后返回
*/
public final String join(Iterable<?> parts);
/**
* 把parts每个元素转换为字符串,再添加连接符之后返回
*/
public final String join(Iterator<?> parts);
/**
* 把parts每个元素转换为字符串,再添加连接符之后返回
*/
public final String join(Object[] parts);
/**
* 给参数里面的每个元素转换为String,再添加连接符之后返回
*/
public final String join(@Nullable Object first, @Nullable Object second, Object... rest);
/**
* 用指定的字符串替换掉null对象
*/
public Joiner useForNull(final String nullText);
/**
* 连接Map的Joiner 设置key, value之间的分隔符
*/
public MapJoiner withKeyValueSeparator(char keyValueSeparator);
/**
* 连接Map的Joiner 设置key, value之间的分隔符
*/
public MapJoiner withKeyValueSeparator(String keyValueSeparator);
}
1.2 Joiner使用实例
@Test
public void joinTest() {
List<String> stringSrc = Lists.newArrayList("C", "Android", "Java");
String resultString = Joiner.on("; ")
.join(stringSrc);
System.out.println(resultString);
}
/**
* useForNull 用指定的值来替换null
*/
@Test
public void useForNullTest() {
String resultString = Joiner.on("; ")
.useForNull("abc")
.join("C", null, "Android", "Java");
System.out.println(resultString);
}
/**
* skipNulls 跳过null
*/
@Test
public void skipNullsTest() {
String resultString = Joiner.on("; ")
.skipNulls()
.join("C", null, "Android", "Java");
System.out.println(resultString);
}
/**
* withKeyValueSeparator
*/
@Test
public void withKeyValueSeparatorTest() {
Map<String, String> mapSrc = new HashMap<>();
mapSrc.put("key0", "value0");
mapSrc.put("key1", "value1");
String resultString = Joiner.on("; ")
.withKeyValueSeparator("&")
.join(mapSrc);
System.out.println(resultString);
}
二 拆分器 -- Splitter
Splitter可以帮助我们制定拆分符对字符串进行拆分。里面也提供了很多使用的方法,比如去掉空格,限制拆分出来的字符串的个数等等。同时还提供了MapSplitter派生类用来把指定格式的字符串拆分到Map里面去。
2.1 Splitter方法介绍
public class Splitter {
/**
* 指定按单个字符拆分
*/
public static Splitter on(char separator);
/**
* 指定按字符匹配器拆分
*/
public static Splitter on(final CharMatcher separatorMatcher);
/**
* 指定按字符串拆分
*/
public static Splitter on(final String separator);
/**
* 指定按正则表达式拆分
*/
@GwtIncompatible // java.util.regex
public static Splitter on(Pattern separatorPattern);
/**
* 指定按正则表达式拆分
*/
@GwtIncompatible // java.util.regex
public static Splitter onPattern(String separatorPattern);
/**
* 创建Splitter对象, 按固定长度拆分;最后一段可能比给定长度短,但不会为空
*/
public static Splitter fixedLength(final int length);
/**
* 从结果中自动忽略空字符串
*/
public Splitter omitEmptyStrings();
/**
* 限制拆分出的字符串数量
*/
public Splitter limit(int limit) {
checkArgument(limit > 0, "must be greater than zero: %s", limit);
return new Splitter(strategy, omitEmptyStrings, trimmer, limit);
}
/**
* 移除结果字符串的前导空白和尾部空白
*/
public Splitter trimResults() {
return trimResults(CharMatcher.whitespace());
}
/**
* 给定匹配器,移除结果字符串的前导匹配字符和尾部匹配字符
*/
// TODO(kevinb): throw if a trimmer was already specified!
public Splitter trimResults(CharMatcher trimmer);
/**
* 按照赵鼎的拆分条件拆分, 返回Iterable<String>
*/
public Iterable<String> split(final CharSequence sequence);
/**
* 按照指定的条件拆分,返回List<String>
*/
public List<String> splitToList(CharSequence sequence);
/**
* 返回MapSplitter并且指定key,value之间的拆分字符串
*/
@Beta
public MapSplitter withKeyValueSeparator(String separator);
/**
* 返回MapSplitter并且指定key,value之间的拆分字符串
*/
@Beta
public MapSplitter withKeyValueSeparator(char separator);
/**
* 返回MapSplitter并且指定key,value之间的拆分规则为Splitter
*/
@Beta
public MapSplitter withKeyValueSeparator(Splitter keyValueSplitter);
2.2 Splitter使用实例
@Test
public void splitTest() {
Iterable<String> iterableList = Splitter.on(',').trimResults() // 移除前面和后面的空白
.omitEmptyStrings() // 去掉null
.split("foo,bar,, qux");
List<String> resultList = Lists.newArrayList(iterableList);
for (String item : resultList) {
System.out.println(item);
}
}
/**
* splitToList 最终直接返回List
*/
@Test
public void splitToListTest() {
List<String> resultList = Splitter.on(',').trimResults().omitEmptyStrings().splitToList("foo,bar,, qux");
for (String item : resultList) {
System.out.println(item);
}
}
/**
* MapSplitter
*/
@Test
public void mapSplitterTest() {
String source = "key0:value0#key1:value1";
Map<String, String> resultMap = Splitter.on("#").withKeyValueSeparator(":").split(source);
for (Map.Entry<String, String> entry : resultMap.entrySet()) {
System.out.println("key: " + entry.getKey() + " value: " + entry.getValue());
}
}
三 字符匹配器 -- CharMatcher
CharMatcher是字符匹配的一个帮助类,CharMatcher主要围绕两件事情来进行:找到匹配的字符、处理匹配的字符。
3.1 CharMatcher方法介绍
CharMatcher创建的static方法 | 解释 | 备注 |
---|---|---|
CharMatcher any() | 返回匹配任何字符的Matcher | |
CharMatcher none() | 返回不匹配所有字符的Matcher | |
CharMatcher whitespace() | 返回匹配所有空白字符的Matcher | |
CharMatcher breakingWhitespace() | 返回匹配所有可换行的空白字符(不包括非换行空白字符,例如"\u00a0")的Matcher | |
CharMatcher ascii() | 返回匹配是否是ASCII字符的Matcher | |
CharMatcher digit() | 返回匹配ASCII数字的Matcher | 不推荐使用了,使用inRange('0', '9')替换 |
CharMatcher javaDigit() | 返回匹配UNICODE数字的Matcher | 不推荐使用了,使用inRange('0', '9')替换实现 |
CharMatcher javaLetter() | 返回匹配字母的Matcher | 不推荐使用了,使用 inRange('a', 'z').or(inRange('A', 'Z') 替换 |
CharMatcher javaLetterOrDigit() | 返回匹配数字或字母的Matcher | 不推荐使用了,使用isLetterOrDigit替换 |
CharMatcher javaUpperCase() | 返回匹配大写的Matcher | 不推荐使用了,使用isUpperCase()替换 |
CharMatcher javaLowerCase() | 返回匹配小写的Matcher | 不推荐使用了,使用isLowerCase()替换 |
CharMatcher javaIsoControl() | 返回匹配ISO控制字符的Matcher, 使用 Charater.isISOControl() 实现 | 也可以使用isISOControl()实现 |
CharMatcher invisible() | 返回匹配所有看不见的字符的Matcher | 不推荐使用了 |
CharMatcher singleWidth() | 返回匹配单字宽字符的Matcher,如中文字就是双字宽 | 不推荐使用了 |
CharMatcher is(char match) | 返回匹配指定字符的Matcher | |
CharMatcher isNot(char match) | 返回不匹配指定字符的Matcher | |
CharMatcher anyOf(CharSequence sequence) | 返回匹配sequence中任意字符的Matcher | |
CharMatcher noneOf(CharSequence sequence) | 返回不匹配sequence中任何一个字符的Matcher | |
CharMatcher inRange(char startInclusive, char endIncludesive) | 返回匹配范围内任意字符的Matcher | |
CharMatcher forPredicate(Predicate<? super Charater> predicate) | 返回使用predicate的apply()判断匹配的Matcher | |
CharMatcher negate() | 返回以当前Matcher判断规则相反的Matcher | |
CharMatcher and(CharMatcher other) | 返回与other匹配条件组合做与来判断的Matcher | |
CharMatcher or(CharMatcher other) | 返回与other匹配条件组合做或来判断的Matcher |
CharMatcher常用方法 | 解释 |
---|---|
boolean matchesAnyOf(CharSequence sequence) | 只要sequence中有任意字符能匹配Matcher,返回true |
boolean matchesAllOf(CharSequence sequence) | sequence中所有字符都能匹配Matcher,返回true |
boolean matchesNoneOf(CharSequence sequence) | sequence中所有字符都不能匹配Matcher,返回true |
int indexIn(CharSequence sequence) | 返回sequence中匹配到的第一个字符的坐标 |
int indexIn(CharSequence sequence, int start) | 返回从start开始,在sequence中匹配到的第一个字符的坐标 |
int lastIndexIn(CharSequence sequence) | 返回sequence中最后一次匹配到的字符的坐标 |
int countIn(CharSequence sequence) | 返回sequence中匹配到的字符计数 |
String removeFrom(CharSequence sequence) | 删除sequence中匹配到到的字符并返回 |
String retainFrom(CharSequence sequence) | 保留sequence中匹配到的字符并返回 |
String replaceFrom(CharSequence sequence, char replacement) | 替换sequence中匹配到的字符并返回 |
String trimFrom(CharSequence sequence) | 删除首尾匹配到的字符并返回 |
String trimLeadingFrom(CharSequence sequence) | 删除首部匹配到的字符 |
String trimTrailingFrom(CharSequence sequence) | 删除尾部匹配到的字符 |
String collapseFrom(CharSequence sequence, char replacement) | 将匹配到的组(连续匹配的字符)替换成replacement |
String trimAndCollapseFrom(CharSequence sequence, char replacement) | 先trim在replace |
3.2 CharMatcher使用实例
针对CharMatcher的使用,我们举几个简单的例子。
@Test
public void matcherNumCharTest() {
// 创建一个匹配数字字符的CharMatcher
CharMatcher numMatcher = CharMatcher.inRange('0', '9');
// 匹配判断(false)
System.out.println(numMatcher.matches('a'));
}
@Test
public void retainFromTest() {
// 创建一个匹配数字字符的CharMatcher
CharMatcher numMatcher = CharMatcher.inRange('0', '9');
// retainFrom保留匹配到的字符(123789)
System.out.println(numMatcher.retainFrom("123abc789"));
}
@Test
public void countInTest() {
// 创建匹配任何字符的Matcher
CharMatcher numMatcher = CharMatcher.any();
// 返回sequence中匹配到的字符个数(9个)
int matcherCount = numMatcher.countIn("abc123abc");
System.out.println("匹配到的字符个数:" + matcherCount);
}
@Test
public void negateTest() {
// 创建了一个匹配字母的Matcher
CharMatcher letterMatcher = CharMatcher.inRange('a', 'z')
.or(CharMatcher.inRange('A', 'Z'));
// 非字母的Matcher negate()规则相反
CharMatcher notLetterMatcher = letterMatcher.negate();
System.out.println(notLetterMatcher.retainFrom("abcABC123"));
}
@Test
public void indexInTest() {
// 创建了一个只匹配a字母的Matcher
CharMatcher letterMatcher = CharMatcher.is('a');
// 非字母的Matcher negate()规则相反
int aStartIndex = letterMatcher.indexIn("123abcabc");
int aEndIndex = letterMatcher.lastIndexIn("123abcabc");
System.out.println("a第一次出现的位置:" + aStartIndex);
System.out.println("a最后一次出现的位置:" + aEndIndex);
}
四 字符集 -- Charsets
guava里面的Charsets可以完全使用StandardCharsets来代替。所以我们干脆直接介绍StandardCharsets了,StandardCharsets比较是JDK里面的东西。StandardCharsets是用来做字符集处理。比如我们String和byte数组之间相互转换的时候可以使用到。
String src = "abc";
byte[] byteDis src.getBytes(StandardCharsets.UTF_8);
StandardCharsets里面的代码也很简答。
public final class StandardCharsets {
private StandardCharsets() {
throw new AssertionError("No java.nio.charset.StandardCharsets instances for you!");
}
/**
* Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the
* Unicode character set
*/
public static final Charset US_ASCII = Charset.forName("US-ASCII");
/**
* ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1
*/
public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
/**
* Eight-bit UCS Transformation Format
*/
public static final Charset UTF_8 = Charset.forName("UTF-8");
/**
* Sixteen-bit UCS Transformation Format, big-endian byte order
*/
public static final Charset UTF_16BE = Charset.forName("UTF-16BE");
/**
* Sixteen-bit UCS Transformation Format, little-endian byte order
*/
public static final Charset UTF_16LE = Charset.forName("UTF-16LE");
/**
* Sixteen-bit UCS Transformation Format, byte order identified by an
* optional byte-order mark
*/
public static final Charset UTF_16 = Charset.forName("UTF-16");
}
五 CaseFormat
CaseFormat是一个枚举,他也是一种字符转换实用工具类,以提供不同的ASCII字符格式之间的转换。比如我们想把lower-hyphen字符转换成lowerCamel,小驼峰大驼峰之间的转换等等。
CaseFormat枚举 | 对应字符串格式 | 解释 |
---|---|---|
LOWER_HYPHEN | lower-hyphen | 全部小写—连接 |
LOWER_UNDERSCORE | lower_underscore | 全部小写下划线连接 |
LOWER_CAMEL | lowerCamel | 小驼峰 |
UPPER_CAMEL | UpperCamel | 大驼峰 |
UPPER_UNDERSCORE | UPPER_UNDERSCORE | 全部大写下划线连接 |
CaseFormat类的用法也很简单。里面就一个方法,public final String to(CaseFormat format, String str) 用于把一种CaseFormat类型对应的字符串转换成另一种CaseFormat对应的字符串。
举一个非常简单的例子。把字符串“CONSTANT_NAME”转换为小驼峰形式“constantName”。 代码如下
@Test
public void test() {
// 把字符串“CONSTANT_NAME”转换成"constantName"
String resultToStr = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, "CONSTANT_NAME");
System.out.println(resultToStr);
}
这里关于Guava字符串处理者几个帮助类的源码我们没怎么讲。里面实现其实不难的。强烈建议大家有时间的时候看一去瞧下。