String manipulation — Google Guava

Preface

In Java, a string represents an immutable sequence of characters and cannot be changed after creation. In our daily work, strings are used very frequently. Skilled operations on them can greatly improve our work efficiency. The protagonist I will introduce today is a core Java library open sourced by Google—Guava, which provides collection types. , Immutable collection, concurrency, I/O, cache, string and many other practical functions. In this article, we will learn to use Strings and Splitter string manipulation tools in Guava.

how to use

Google Guava 会同步到 Maven Central 中,所以,如果你是 Maven 项目的话只需要在 pom.xml 文件中引入如下依赖即可:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>28.2-jre</version>
</dependency>

For Gradle projects, just introduce the following dependencies in build.gradle:

compile group:'com.google.guava', name:'guava', version: '28.2-jre'
PS: 28.2-jre is the latest version at the time of writing this article, you can check the current latest version from Maven Central.

Why do we need to introduce a class library

Google Guava provides a lot of practical static methods, which can solve some repetitive tasks that developers have to complete in development. Of course, we can also do this work ourselves, but the introduction of class libraries will reduce the possibility of errors. After all, these class libraries have been validated in production for many years. For example, a method commonPrefix provided by Strings in the class library accepts two strings and returns the common prefix between the two strings (eg: abcd and abef return ab). You can imagine in your mind how to write the code to complete the operation when facing such a requirement in the application code. To implement this function yourself, it still takes some time, and you also need to consider various boundary exceptions. Happening. This is one of the greatest values ​​provided to us by class libraries, so when a certain function we need can be used as a tool method, we should first find some existing class libraries and use them proficiently instead of ourselves To achieve. In summary, there are several reasons for using class libraries:

Someone in the Google Guava library has thoroughly tested it, and the probability of bugs appearing is much smaller than our own implementation.

As part of Google Guava, various test cases already exist to test the implementation of the utility. If we write the code ourselves, we may have to write and maintain their tests.

Strings

Google Guava has many useful tool classes and methods, which cannot be covered in one article. In this article, only two tool classes related to string manipulation will be introduced. First of all, the first is the Strings class, which provides practical methods to manipulate String and CharSequence.

nullToEmpty、emptyToNull 和 isNullOrEmpty

The function of the nullToEmpty method is: if the incoming string is null, it returns an empty string "", otherwise, it returns an empty string, otherwise it returns the passed string as it is.

@Test
public void testStringsOfNullToEmpty() {
    System.out.println(Strings.nullToEmpty("mghio"));         // mghio
    System.out.println(Strings.nullToEmpty(""));              // ""
    System.out.println(Strings.nullToEmpty(null));            // ""
    System.out.println(Strings.nullToEmpty(null).isEmpty());  // true
}

The function of emptyToNull method is: it is the opposite of nullToEmpty. If an empty string is passed in, it returns null, otherwise it returns the original string.


@Test
public void testStringsOfEmptyToNull() {
    System.out.println(Strings.emptyToNull("mghio"));  // mghio
    System.out.println(Strings.emptyToNull(null));     // null
    System.out.println(Strings.emptyToNull(""));       // null
}

The function of isNullOrEmpty method is: if the incoming string is null or empty, it returns true, otherwise it returns false.


@Test
public void testStringsOfIsNullOrEmpty() {
    System.out.println(Strings.isNullOrEmpty("mghio"));  // false
    System.out.println(Strings.isNullOrEmpty(""));       // true
    System.out.println(Strings.isNullOrEmpty(null));     // true
}

padStart and padEnd

These two methods have three parameters, namely: the input string, the minimum length and the characters to be filled. It inserts characters into the beginning of the input string as many times as necessary to make the length of the input string equal to the minimum passed in length.


@Test
public void testStringsOfPadStart() {
    System.out.println(Strings.padStart("9527", 6, '0'));    // 009527
    System.out.println(Strings.padStart("123456", 6, '0'));  // 123456
}

In the first line of code, 0 will be filled twice to make the final string length equal to the minimum length we passed in (6). In the second line of code, the input string length itself has the required minimum length, so the padEnd method is similar to the above method without padding, except that it pads at the end of the character instead of at the beginning.


@Test
public void testStringsOfPadEnd() {
    System.out.println(Strings.padEnd("9527", 6, '0'));    // 952700
    System.out.println(Strings.padEnd("123456", 6, '0'));  // 123456
}

repeat

This method needs to pass in a string and a number of repetitions count, it returns a string composed of the original string, the string is repeated count times.

@Test
public void testStringsRepeat() {
    System.out.println(Strings.repeat("mghio", 3));  // mghiomghiomghio
}

commonPrefix 和 commonSuffix

The commonPrefix method returns the largest common prefix between the two input strings, and the commonSuffix method returns the largest common suffix between the two input strings.


@Test
public void testStrings() {
    System.out.println(Strings.commonPrefix("mghio9527", "mghio666"));  // mghio
    System.out.println(Strings.commonSuffix("iammghio", "nicemghio"));  // mghio
}

Splitter

The function provided by the Splitter class is just as its name (off-topic: a good name is important), it is used to split a string into multiple substrings according to the provided separator. We can get an instance of Splitter by passing in a splitter. With the splitter, we can split the string according to the configuration of the splitter.


@Test
public void testSplitterOfSplit() {
    Iterable<String> result = Splitter.on(",").split("m,g,h,i,o");
    System.out.println(result);  // [m, g, h, i, o]
}

In the above example, a comma is used to split. Therefore, it splits the incoming string m, g, h, i, o into an Iterable, and then when we iterate over it, it will output [m, g, h , i, o].

Get the Splitter instance

on 和 onPattern

Now, let's take a look at the various methods of obtaining a Splitter. There are various overloaded versions of the on method. They use characters, strings or regular expressions as delimiters. We can also pass Pattern instances as strings to the onPattern method.


@Test
public void testSplitterOfOn() {
    Splitter wordSplitter = Splitter.on(":;");
    // 下面这行输出结果 [the, text, is, separated, by, colon, semicolon]
    System.out.println(wordSplitter.split("the:;text:;is:;separated:;by:;colon:;semicolon"));
    Splitter patternBasedSplitter = Splitter.on(Pattern.compile("\\s+"));
    System.out.println(patternBasedSplitter.split("abc   dmg hio"));         // [abc, dmg, hio]
    System.out.println(Splitter.onPattern("\\s+").split("www   mghio cn"));  // [www, mghio, cn]
}

fixedLength

fixedLength is also one of the most useful methods. It can divide a string into equal parts of a given length. It should be noted that the last part may be less than the given length.


@Test
public void testSplitterOfFixedLength() {
    Splitter fixedLengthSplitter = Splitter.fixedLength(3);
    System.out.println(fixedLengthSplitter.split("iammghiojava"));          // [iam, mgh, ioj, ava]
    System.out.println(fixedLengthSplitter.split("https://www.mghio.cn"));  // [htt, ps:, //w, ww., mgh, io., cn]
}

Splitter modifier method

Splitter also provides common methods that can be used to change or modify the behavior of the Splitter.

trimResults

This method can remove the leading and trailing spaces from the result string of the generated splitter.


@Test
public void testSplitterOfTrimResult() {
    Splitter commaSplitter = Splitter.on(",");
    System.out.println(commaSplitter.split("m, g, h, i, o"));         // [m,  g,  h,  i,  o]
    Splitter commaSplitterWithTrim = commaSplitter.trimResults();
    System.out.println(commaSplitterWithTrim.split("m, g, h, i, o")); // [m, g, h, i, o]
}

Note that the first split result has a space before the string g, h, i, o, after using the trimResults method, these leading spaces will be removed

omitEmptyStrings

This method will ignore all empty strings from the result.


@Test
public void testSplitterOfOmitEmptyStrings() {
    Splitter commaSplitter = Splitter.on(",");
    System.out.println(commaSplitter.split("m,,g,h,i,o"));                   // [m, , g, h, i, o]
    Splitter commaSplitterWithNoEmptyString = commaSplitter.omitEmptyStrings();
    System.out.println(commaSplitterWithNoEmptyString.split("m,,g,h,i,o"));  // [m, g, h, i, o]
}

The commaSplitterWithNoEmptyString above will remove the result of an empty string from the output.

limit

This method returns a splitter equivalent to the original splitter, but it will stop splitting after reaching the specified input limit, and output the remaining result string as one item, that is, we can pass in The parameter specifies the maximum number of items present in the result. Note that when this method omits empty strings, the omitted strings are not counted. .


@Test
public void testSplitterOfLimit() {
    Splitter commaSplitter = Splitter.on(",");
    Splitter limitingCommaSplitter = commaSplitter.limit(3);
    System.out.println(limitingCommaSplitter.split("i,m,g,h,i,o"));  // [i, m, g,h,i,o]
}

One thing to note is that Splitter is immutable (this is similar to String), so any modifier method that calls it will return a new Splitter and will not modify the original Splitter.

@Test
public void testSplitterImmutable() {
    Splitter splitter = Splitter.on('/');
    System.out.println("Before: " + splitter);  // Before: com.google.common.base.Splitter@33b37288
    splitter.trimResults();                     // do nothing
    System.out.println("First: " + splitter);   // First: com.google.common.base.Splitter@33b37288
    splitter = splitter.trimResults();          // the returned splitter to be assigned
    System.out.println("Second: " + splitter);  // Second: com.google.common.base.Splitter@77a57272
}

splitToList

The split method we have used earlier, it returns an Iterable object. The splitToList method here returns a List. Since the split method returns Iterable, it is lazy.


@Test
public void testSplitterOfSplitToList() {
    Splitter commaSplitter = Splitter.on(",");
    List<String> result = commaSplitter.splitToList("m,g,h,i,o");
    System.out.println(result);  // [m, g, h, i, o]
}

MapSplitter

MapSplitter, as its name suggests, is used to split a string into Map objects. We can use the withKeyValueSeparator method to obtain the MapSplitter object from the Splitter, which receives a character, string, or Splitter object as a parameter. First, split the string into multiple items according to the original splitter, and then use the splitter passed to the withKeyValueSeparator method to divide each item into Map key-value pairs.


@Test
public void testSplitterOfWithKeyValueSeparator() {
    Splitter commaSplitter = Splitter.on(',');
    Splitter.MapSplitter keyValueSplitter = commaSplitter.withKeyValueSeparator('=');
    Map<String, String> map = keyValueSplitter.split("name=mghio,blog=mghio.cn");
    System.out.println(map);  // {name=mghio, blog=mghio.cn}
}

As you can see from the result, it is split into two entries (name=mghio and blog=mghio.cn). One more thing to note is: if we specify any modifiers on the original splitter, they Only applicable to this splitter, not to MapSplitter.


@Test
public void testSplitterOfWithKeyValueSeparatorAndModifiers() {
    Splitter originalSplitter = Splitter.on(",").trimResults();
    Splitter.MapSplitter keyValueSplitter = originalSplitter.withKeyValueSeparator('=');
    // 输出结果:{name  =mghio, blog=   mghio.cn}
    System.out.println(keyValueSplitter.split("name  =mghio,   blog=   mghio.cn"));  
}

It can be seen from the above results that trimResults modification method is only applicable to the original splitter. Therefore, the space at the beginning of the blog has been removed (when using, to split the original string), but the space at the beginning of mghio.cn will not be removed (when using = to split the key value).

The last thing to note is that the MapSplitter class is marked as @Beta, which means that the classes and methods related to MapSplitter in the class library are experimental and can be changed (in a discontinuous manner), and may even be deleted in future versions.

to sum up

In this article, I introduced the Google Guava library and the benefits of using it in a project or application, and how to import it into our application. Then, I introduced some basic usages of string manipulation tools (Strings and Splitter) in the Guava library. Of course, this is just the tip of the iceberg. The Guava library also provides many other useful basic functions. We need to query related documents and learn by ourselves. Understand, interested friends can go to see its implementation source code, the code of this library is very elegant.

Guess you like

Origin blog.51cto.com/15075507/2607584