在字符串中替换多个字符串

Substituting multiple Strings in String

我知道有很多与类似问题相关的问题和答案,但我找不到我的问题的答案。这是我的一小段代码:

    private String substitute(String text) {
      List<Macro> macros = getMacros();

      for (Macro macro : macros) {
        text = StringUtils.replace(text, macro.getKey(), macro.getValue());
      }
      return text;
    }  
  1. 这是一个替代文本字符串中的多个宏变量的好方法吗?这会在每个循环中创建一个新的 String 对象,所以我想知道是否有更好的方法来做到这一点。理想情况下我会使用 Apache Commons StrSubstitutor class 但我不能因为 tokens/macros 的格式(不同的格式而不是固定的 prefix/suffix 之间)。由于性能问题,我也不想使用 Regex。
  2. 根据工作中的一些编码规则,我需要将参数标记为final。我想知道这是否真的是好的做法。我知道字符串是不可变的,而且我知道每当我调用 StringUtils.replace() 时,它都会 return 给我一个新的字符串对象。但是我想知道这里的 String 参数是否应该按照建议标记为 final 并且在方法中做这样的事情:

    String result = text;
    for (Macro macro : macros) {
      result = StringUtils.replace(result, macro.getKey(), macro.getValue());
    }
    

    我就是不喜欢这个。

如有任何帮助,我们将不胜感激。谢谢。

您可以使用 apache velocity 将带有键的字符串替换为带有值的等效字符串。

如果您对性能有一些顾虑,可以使用 StringBuilder,它允许您将文本参数声明为最终参数:

private String substitute(final String text) {
    List<Macro> macros = getMacros();
    StringBuilder stringBuilder=new StringBuilder(text);
    for(Macro macro: macros) {
        int index=stringBuilder.indexOf(macro.getKey());
        if (index!=-1) {
            stringBuilder.replace(index, index+macro.getKey().length(), macro.getValue());
        }
    }
    return stringBuilder.toString();
}

你的担心似乎是有道理的。字符串是不可变的,因此它会创建多个对象。您应该使用 StringBuilder 或 StringBuffer。

我为你写了一个示例。从这里构建

private static String substitute(String text) {
        List<Macro> macros = getMacros();
        StringBuffer st = new StringBuffer(text);

        for (Macro macro : macros) {
            int start = st.indexOf(macro.getKey());
            if (start != -1) {
                st.replace(start, start + macro.getKey().length(), macro.getValue());
            }
        }
        return st.toString();
    }

干杯!!