public static String format(String str, Object... args) {
    // TODO(chaokunyang) optimize performance.
    // TODO(chaokunyang) support `$xxx`.
    StringBuilder builder = new StringBuilder(str);
    if (args.length % 2 != 0) {
      throw new IllegalArgumentException(
          "args length must be multiple of 2, but get " + args.length);
    }
    Map<String, String> values = new HashMap<>();
    for (int i = 0; i < args.length; i += 2) {
      values.put(args[i].toString(), args[i + 1].toString());
    }

    for (Map.Entry<String, String> entry : values.entrySet()) {
      int start;
      String pattern = "${" + entry.getKey() + "}";
      String value = entry.getValue();

      // Replace every occurrence of %(key) with value
      while ((start = builder.indexOf(pattern)) != -1) {
        builder.replace(start, start + pattern.length(), value);
      }
    }

    return builder.toString();
  }
@Test
  public void testFormat() {
    assertEquals(StringUtils.format("${a}, ${b}", "a", 1, "b", "abc"), "1, abc");
  }