1. 概述

在这个教程中,我们将学习在Java中以多种方式截断字符串到所需的字符数。

首先,我们将探讨使用Java标准库自身来实现这一目标的方法。接着,我们将关注一些流行的第三方库。

2. 使用Java标准库截断字符串

Java提供了多种方便的方式来截断字符串。让我们来看看具体的方法。

2.1. 使用Stringsubstring()方法

String类提供了一个便捷的名为substring()的方法。顾名思义,substring()返回给定字符串在指定索引之间的部分。

static String usingSubstringMethod(String text, int length) {
    if (text.length() <= length) {
        return text;
    } else {
        return text.substring(0, length);
    }
}

在上述示例中,如果指定的长度大于text的长度,我们直接返回text。这是因为将一个大于字符串字符数的长度传递给substring()会抛出IndexOutOfBoundsException

否则,我们将从索引0开始并延伸到(但不包括)索引length处的子字符串返回。

让我们通过测试用例验证这一点:

static final String TEXT = "Welcome to baeldung.com";

@Test
public void givenStringAndLength_whenUsingSubstringMethod_thenTrim() {

    assertEquals(TrimStringOnLength.usingSubstringMethod(TEXT, 10), "Welcome to");
}

如我们所见,开始索引是包含在内的,而结束索引是不包含在内的。因此,索引length处的字符不会被包含在返回的子字符串中。

2.2. 使用Stringsplit()方法

另一种截断字符串的方式是使用split()方法,它使用正则表达式将字符串分割成多个部分。

这里我们将使用正则表达式的特性,即正向前瞻,匹配从字符串开头开始的指定数量的字符:

static String usingSplitMethod(String text, int length) {

    String[] results = text.split("(?<=\\G.{" + length + "})");

    return results[0];
}

results数组的第一个元素将是我们的截断后的String,如果length大于text,则为原始String

让我们测试我们的方法:

@Test
public void givenStringAndLength_whenUsingSplitMethod_thenTrim() {

    assertEquals(TrimStringOnLength.usingSplitMethod(TEXT, 13), "Welcome to ba");
}

2.3. 使用Pattern

同样,我们可以使用Pattern类编译一个正则表达式,该正则表达式匹配字符串的开始,直到指定的字符数。

例如,我们可以使用{1,” + length + “}.*这个正则表达式,它匹配至少一个且最多length个字符:

static String usingPattern(String text, int length) {

    Optional<String> result = Pattern.compile(".{1," + length + "}")
      .matcher(text)
      .results()
      .map(MatchResult::group)
      .findFirst();

    return result.isPresent() ? result.get() : EMPTY;

}

如上所示,在将正则表达式编译为Pattern后,我们可以使用Patternmatcher()方法根据该正则表达式解释我们的String。然后,我们可以对结果进行分组,并返回第一个,即我们的截断后的String

现在让我们添加一个测试用例来验证代码是否按预期工作:

@Test
public void givenStringAndLength_whenUsingPattern_thenTrim() {

    assertEquals(TrimStringOnLength.usingPattern(TEXT, 19), "Welcome to baeldung");
}

2.4. 使用CharSequencecodePoints()方法

Java 9提供了codePoints()方法,将String转换为一系列的码点值

让我们看看如何结合流API使用此方法来截断字符串:

static String usingCodePointsMethod(String text, int length) {

    return text.codePoints()
      .limit(length)
      .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
      .toString();
}

在这里,我们使用了Streamlimit()方法限制流的长度到给定的length。然后我们使用StringBuilder构建截断后的字符串。

接下来,让我们验证我们的方法是否有效:

@Test
public void givenStringAndLength_whenUsingCodePointsMethod_thenTrim() {

    assertEquals(TrimStringOnLength.usingCodePointsMethod(TEXT, 6), "Welcom");
}

3. Apache Commons库

Apache Commons Lang库包含一个用于操作StringStringUtils类。

首先,让我们将Apache Commons的依赖项添加到我们的pom.xml文件中:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.14.0</version>
</dependency>

3.1. 使用StringUtilsleft()方法

StringUtils有一个有用的静态方法left()StringUtils.left()以安全的方式返回字符串的指定数量左侧字符:

static String usingLeftMethod(String text, int length) {

    return StringUtils.left(text, length);
}

3.2. 使用StringUtilstruncate()方法

或者,我们可以使用StringUtils.truncate()来达到相同的目的:

public static String usingTruncateMethod(String text, int length) {

    return StringUtils.truncate(text, length);
}

4. Guava库

除了使用核心Java方法和Apache Commons库截断String,我们还可以使用Guava。首先,让我们在pom.xml文件中添加Guava的依赖项

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

现在我们可以使用Guava的Splitter类来截断我们的String

static String usingSplitter(String text, int length) {
    
    Iterable<String> parts = Splitter.fixedLength(length)
      .split(text);

    return parts.iterator()
      .next();
}

我们使用Splitter.fixedLength()将字符串分割成指定长度的多个部分。然后,我们返回结果的第1个元素。

5. 总结

在这篇文章中,我们学习了在Java中以多种方式截断字符串到特定字符数的方法。

我们首先探讨了一些使用Java标准库的方法,然后使用了几个第三方库来截断String

如往常一样,本文中使用的代码可以在GitHub上的相关项目中找到。