1. 概述
在这个教程中,我们将学习在Java中以多种方式截断字符串到所需的字符数。
首先,我们将探讨使用Java标准库自身来实现这一目标的方法。接着,我们将关注一些流行的第三方库。
2. 使用Java标准库截断字符串
Java提供了多种方便的方式来截断字符串。让我们来看看具体的方法。
2.1. 使用String
的substring()
方法
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. 使用String
的split()
方法
另一种截断字符串的方式是使用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
后,我们可以使用Pattern
的matcher()
方法根据该正则表达式解释我们的String
。然后,我们可以对结果进行分组,并返回第一个,即我们的截断后的String
。
现在让我们添加一个测试用例来验证代码是否按预期工作:
@Test
public void givenStringAndLength_whenUsingPattern_thenTrim() {
assertEquals(TrimStringOnLength.usingPattern(TEXT, 19), "Welcome to baeldung");
}
2.4. 使用CharSequence
的codePoints()
方法
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();
}
在这里,我们使用了Stream
的limit()
方法限制流的长度到给定的length
。然后我们使用StringBuilder
构建截断后的字符串。
接下来,让我们验证我们的方法是否有效:
@Test
public void givenStringAndLength_whenUsingCodePointsMethod_thenTrim() {
assertEquals(TrimStringOnLength.usingCodePointsMethod(TEXT, 6), "Welcom");
}
3. Apache Commons库
Apache Commons Lang库包含一个用于操作String
的StringUtils
类。
首先,让我们将Apache Commons的依赖项添加到我们的pom.xml
文件中:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.14.0</version>
</dependency>
3.1. 使用StringUtils
的left()
方法
StringUtils
有一个有用的静态方法left()
。StringUtils.left()
以安全的方式返回字符串的指定数量左侧字符:
static String usingLeftMethod(String text, int length) {
return StringUtils.left(text, length);
}
3.2. 使用StringUtils
的truncate()
方法
或者,我们可以使用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上的相关项目中找到。