Google Guava 字符串处理

       为了方便我们对字符串的处理,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字符串处理者几个帮助类的源码我们没怎么讲。里面实现其实不难的。强烈建议大家有时间的时候看一去瞧下。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容

  • 目前Google Guava在实际应用中非常广泛,本篇博客将以博主对Guava使用的认识以及在项目中的经验来给大家...
    java高并发阅读 1,637评论 0 8
  • 目前Google Guava在实际应用中非常广泛,本篇博客将以博主对Guava使用的认识以及在项目中的经验来给大家...
    张丰哲阅读 15,253评论 12 184
  • 一:官方教程 网址:http://blog.csdn.net/axi295309066/article/detai...
    漫步_2310阅读 1,320评论 0 1
  • 本文是对 Guava 中 Splitter 的学习介绍。欢迎加入学习项目: LearningGuava。 使用示例...
    天未的博客阅读 17,734评论 0 6
  • 如若沧海有泪,岂独巫山无云。只待风花雪月落尽,在泛黄的流年镌刻美丽的宿缘。今夜,远去了兰舟,远去了芳草;不想柳舞,...
    西子岸香阅读 472评论 0 7