2024/04/29

Guava String Utilities 1

Joiner

可連接多個 string,同時避免遇到 null 會發生問題

joiner configuration methods 永遠會回傳新的 Joiner 物件,因此 Joiner 是 thread safe 的

    @Test
    public void joiner() {
        Joiner joiner = Joiner.on("; ").skipNulls();
        String joinresult = joiner.join("Harry", null, "Ron", "Hermione");

        assertEquals("Harry; Ron; Hermione", joinresult);

        Joiner joiner2 = Joiner.on("; ").useForNull("?");
        String joinresult2 = joiner2.join("Harry", null, "Ron", "Hermione");
        assertEquals("Harry; ?; Ron; Hermione", joinresult2);

        String joinresult3 = Joiner.on(",").join(Arrays.asList(1, 5, 7));
        assertEquals("1,5,7", joinresult3);
    }

Splitter

原本的 String.split 有些奇怪的回傳結果,Splitter提供多個 method,可以自己決定回傳的結果內容。另外 Splitter 可以套用 Pattern, char, Stirng 或 CharMatcher 作為分割標準

Factory method

Method Description Example
Splitter.on(char) 以字元分割 Splitter.on(';')
Splitter.on(CharMatcher) 以一組字元分割 Splitter.on(CharMatcher.BREAKING_WHITESPACE)
Splitter.on(CharMatcher.anyOf(";,."))
Splitter.on(String) 以字串分割 Splitter.on(", ")
Splitter.on(Pattern) 以 regular expression 分割 Splitter.onPattern("\r?\n")
Splitter.onPattern(String)
Splitter.fixedLength(int) 固定長度分割 Splitter.fixedLength(3)

Modifier methods

Method Description Example Result
omitEmptyString() 忽略 empty string Splitter.on(',').omitEmptyStrings().split("a,,c,d") "a", "c", "d"
trimResults() 去掉 whitespace Splitter.on(',').trimResults().split("a, b, c, d") "a", "b", "c", "d"
trimResults(CharMatcher) 去掉一組字元(最前面&最後面) Splitter.on(',').trimResults(CharMatcher.is('')).split("_a ,_b ,c__") "a ", "b_ ", "c"
limit(int) 最多只分割為 int 個字串後,就不再分割 Splitter.on(',').limit(3).split("a,b,c,d") "a", "b", "c,d"

從 split() 改用 splitToList 會回傳 List

@Test
    public void splitter() {
        String[] split1 = ",a,,b,".split(",");
        // 原生 split 會自動去掉最後一個 ""
        // "", "a", "", "b"
        assertEquals("[, a, , b]", Arrays.toString(split1));

        Iterable<String> split2 =
                Splitter.on(',')
                .trimResults()
                .omitEmptyStrings()
                .split("foo,bar,,   qux");
        // "foo", "bar", "qux"
        assertEquals("[foo, bar, qux]", split2.toString());

        Iterable<String> split3 = Splitter.on(',').omitEmptyStrings().split("a,,c,d");
        // "a", "c", "d"
        assertEquals("[a, c, d]", split3.toString());

        Iterable<String> split4 = Splitter.on(',').trimResults().split("a, b, c, d");
        // "a", "b", "c", "d"
        assertEquals("[a, b, c, d]", split4.toString());

        Iterable<String> split5 = Splitter.on(',').trimResults(CharMatcher.is('_')).split("_a ,_b_ ,c__");
        //"a ", "b_ ", "c"
        assertEquals("[a , b_ , c]", split5.toString());

        Iterable<String> split6 = Splitter.on(',').limit(3).split("a,b,c,d");
        //"a", "b", "c,d"
        assertEquals("[a, b, c,d]", split6.toStringa
());


        // 改用 splitToList 會回傳 List<String>
        List<String> split7 = Splitter.on(',').omitEmptyStrings().splitToList("a,,c,d");
    }

How to use Joiner Splitter

Convert List into String Using Joiner

    @Test
    public void whenConvertListToString_thenConverted() {
        List<String> names = Lists.newArrayList("Taipei", "Taichung", "Kaohsiung");
        String result = Joiner.on(",").join(names);

        assertEquals(result, "Taipei,Taichung,Kaohsiung");
    }

Convert Map to String Using Joiner

    @Test
    public void whenConvertMapToString_thenConverted() {
        Map<String, Integer> salary = Maps.newHashMap();
        salary.put("Taipei", 1000);
        salary.put("Taichung", 1500);
        String result = Joiner.on(" , ").withKeyValueSeparator(" = ")
                .join(salary);

        assertTrue(result.contains("Taipei = 1000"));
        assertTrue(result.contains("Taichung = 1500"));
    }

Join Nested Collections

    @Test
    public void whenJoinNestedCollections_thenJoined() {
        List<ArrayList<String>> nested = Lists.newArrayList(
                Lists.newArrayList("apple", "banana", "orange"),
                Lists.newArrayList("cat", "dog", "bird"),
                Lists.newArrayList("John", "Jane", "Adam"));
        String result = Joiner.on(";").join(Iterables.transform(nested,
                new com.google.common.base.Function<List<String>, String>() {
                    @Override
                    public String apply(List<String> input) {
                        return Joiner.on("-").join(input);
                    }
                }));

        assertTrue(result.contains("apple-banana-orange"));
        assertTrue(result.contains("cat-dog-bird"));
        assertTrue(result.contains("John-Jane-Adam"));
    }

Handle Null Values While Using Joiner

    @Test
    public void whenConvertListToStringAndSkipNull_thenConverted() {
        List<String> names = Lists.newArrayList("John", null, "Jane", "Adam", "Tom");
        String result = Joiner.on(",").skipNulls().join(names);

        assertEquals(result, "John,Jane,Adam,Tom");
    }

    @Test
    public void whenUseForNull_thenUsed() {
        List<String> names = Lists.newArrayList("John", null, "Jane", "Adam", "Tom");
        String result = Joiner.on(",").useForNull("nameless").join(names);

        assertEquals(result, "John,nameless,Jane,Adam,Tom");
    }

Create Map From String Using Splitter

    @Test
    public void whenCreateMapFromString_thenCreated() {
        String input = "John=first,Adam=second";
        Map<String, String> result = Splitter.on(",")
                .withKeyValueSeparator("=")
                .split(input);

        assertEquals("first", result.get("John"));
        assertEquals("second", result.get("Adam"));
    }

Split String With Multiple Separators

    @Test
    public void whenSplitStringOnMultipleSeparator_thenSplit() {
        String input = "apple.banana,,orange,,.";
        List<String> result = Splitter.onPattern("[.,]")
                .omitEmptyStrings()
                .splitToList(input);

        assertTrue(result.contains("apple"));
        assertTrue(result.contains("banana"));
        assertTrue(result.contains("orange"));
    }

Split a String at Specific Length

    @Test
    public void whenSplitStringOnSpecificLength_thenSplit() {
        String input = "Hello world";
        List<String> result = Splitter.fixedLength(3).splitToList(input);
        //Hel", "lo ", "wor", "ld"
        assertEquals("[Hel, lo , wor, ld]", result.toString());
    }

Limit the Split Result

    @Test
    public void whenLimitSplitting_thenLimited() {
        String input = "a,b,c,d,e";
        List<String> result = Splitter.on(",")
                .limit(4)
                .splitToList(input);

        assertEquals(4, result.size());
        // ["a", "b", "c", "d,e"]
        assertEquals("[a, b, c, d,e]", result.toString());
    }

References

StringsExplained · google/guava Wiki · GitHub

Guava - Join and Split Collections | Baeldung

沒有留言:

張貼留言