1. 概述

在这个教程中,我们将讨论Java中的字符串插值。我们将探讨几个不同的示例,并深入讲解其中的细节。

2. Java中的字符串插值

字符串插值是一种简单而精确的方法,用于将变量值插入到字符串中。 它允许用户在处理过的字符串字面量中直接嵌入变量引用。相比之下,Java在字符串插值方面缺乏与诸如Scala等语言的原生支持。

然而,在Java中实现这种行为有一些方法。在接下来的章节中,我们将逐一解释这些方法。

3. 加号运算符

首先,我们有加号运算符。我们可以使用加号运算符将变量和字符串值连接起来。变量会被其值替换,从而实现字符串的插值或连接:

@Test
public void givenTwoString_thenInterpolateWithPlusSign() {
    String EXPECTED_STRING = "String Interpolation in Java with some Java examples.";
    String first = "Interpolation";
    String second = "Java";
    String result = "String " + first + " in " + second + " with some " + second + " examples.";
    assertEquals(EXPECTED_STRING, result);
}

如上例所示,通过这个运算符,结果字符串包含了变量的值与其他字符串值的合并。由于它可以根据特定需求进行调整,这种方法是简单且有价值的字符串连接方式。使用运算符时,我们不需要在文本中添加引号。

4. format() 函数

另一种方法是使用String类的格式化函数。与加号运算符不同,这里我们需要使用占位符来获得期望的字符串插值结果:

@Test
public void givenTwoString_thenInterpolateWithFormat() {
    String EXPECTED_STRING = "String Interpolation in Java with some Java examples.";
    String first = "Interpolation";
    String second = "Java";
    String result = String.format("String %s in %s with some %s examples.", first, second, second);
    assertEquals(EXPECTED_STRING, result);
}

此外,如果我们想避免在format调用中重复变量,可以引用特定的参数:

@Test
public void givenTwoString_thenInterpolateWithFormatStringReference() {
    String EXPECTED_STRING = "String Interpolation in Java with some Java examples.";
    String first = "Interpolation";
    String second = "Java";
    String result = String.format("String %1$s in %2$s with some %2$s examples.", first, second);
    assertEquals(EXPECTED_STRING, result);
}

现在,我们减少了不必要的变量重复,而是使用了参数列表中参数的索引。

5. StringBuilder

我们的下一个方法是StringBuilder类。我们创建一个StringBuilder对象,然后调用append()方法构建字符串。在这个过程中,我们的变量被添加到最终的字符串中:

@Test
public void givenTwoString_thenInterpolateWithStringBuilder() {
    String EXPECTED_STRING = "String Interpolation in Java with some Java examples.";
    String first = "Interpolation";
    String second = "Java";
    StringBuilder builder = new StringBuilder();
    builder.append("String ")
      .append(first)
      .append(" in ")
      .append(second)
      .append(" with some ")
      .append(second)
      .append(" examples.");
    String result = builder.toString();
    assertEquals(EXPECTED_STRING, result);
}

如代码示例所示,我们可以通过链式调用append()函数,接受参数作为变量(在这个例子中,是两个字符串)来与必要的文本一起插入字符串。

6. MessageFormat

使用MessageFormat类是获取Java中字符串插值的不太为人知的方法。通过MessageFormat,我们可以创建无需担心底层语言的拼接消息。这是为用户提供界面的消息的标准方法。它接收一个对象集合,格式化其中的字符串,并在适当的位置插入它们。

MessageFormatformat()方法与Stringformat()方法非常相似,只是占位符的写法不同。例如,{0}, {1}, {2}等索引在这种函数中代表占位符:

@Test
public void givenTwoString_thenInterpolateWithMessageFormat() {
    String EXPECTED_STRING = "String Interpolation in Java with some Java examples.";
    String first = "Interpolation";
    String second = "Java";
    String result = MessageFormat.format("String {0} in {1} with some {1} examples.", first, second);
    assertEquals(EXPECTED_STRING, result);
}

在性能方面,StringBuilder仅向动态缓冲区追加文本;而MessageFormat会在追加数据之前解析给定的格式。因此,StringBuilder在效率上优于MessageFormat

7. Apache Commons

最后,我们有来自Apache CommonsStringSubstitutor。在这个类的上下文中,变量的值会替换包含在字符串中的变量。此类接受一段文本并替换所有变量。默认情况下,变量的定义是${variableName}。构造函数和设置方法可用于更改前缀和后缀。通常,变量值的解析涉及使用一个映射。然而,我们可以通过使用系统属性或提供专门的变量解析器来解决它们:

@Test
public void givenTwoString_thenInterpolateWithStringSubstitutor() {
    String EXPECTED_STRING = "String Interpolation in Java with some Java examples.";
    String baseString = "String ${first} in ${second} with some ${second} examples.";
    String first = "Interpolation";
    String second = "Java";
    Map<String, String> parameters = new HashMap<>();
    parameters.put("first", first);
    parameters.put("second", second);
    StringSubstitutor substitutor = new StringSubstitutor(parameters);
    String result = substitutor.replace(baseString);
    assertEquals(EXPECTED_STRING, result);
}

从我们的代码示例来看,我们创建了一个映射。键名与我们在字符串中将要替换的变量名称相同。然后,我们将每个键对应的值放入映射中。接着,我们将映射作为构造函数参数传递给StringSubstitutor类。最后,实例化对象调用replace()函数。这个函数接收带有占位符的文本作为参数。因此,我们得到了一个插值后的文本。就这样,简单明了。

8. 总结

在这篇文章中,我们简要介绍了什么是字符串插值,并学习了如何在Java语言中使用原生Java运算符和String类的format()方法实现这一功能。最后,我们探讨了MessageFormatApache Commons中的StringSubstitutor等不太为人知的选择。如往常一样,代码可以在GitHub上找到。