Pregunta

Tengo un método de servicio que toma una Cadena y luego reemplaza las etiquetas en la Cadena con elementos de una biblioteca de etiquetas. De la siguiente manera:

for( MetaDataDTO tag : tagValues )
{
    message = message.replace( tag.getKey(), tag.getText1() );
}

Obviamente; Esto hace un montón de nuevas cadenas y es MALO. Pero el método de reemplazo de StringBuilder es engorroso de usar para múltiples cadenas dentro de una cadena. ¿Cómo puedo hacer que mi método sea más eficiente?

Es para usar con bloques de texto como:

Estimado # firstName #, su solicitud para # applicationType # ha sido # aprobadaRechazada # lo siento.

Donde # firstName #, etc. son las claves en una base de datos de metadatos. También es posible que las etiquetas no estén rodeadas de caracteres hash.

¿Fue útil?

Solución 2

Gracias por su ayuda chicos. Ciertamente aprendí más sobre Java. Aquí está mi solución. De esta manera, es posible admitir diferentes etiquetas de aspecto dentro de las etiquetas:

private static String replaceAllTags(String message, Map< String, String > tags)
{
    StringBuilder sb = new StringBuilder( message );
    boolean tagFound = false;
    /**
     * prevent endless circular text replacement loops
     */
    long recurrancyChecker = 5000;

    do
    {
        tagFound = false;
        Iterator it = tags.entrySet().iterator();
        while( it.hasNext() )
        {
            Map.Entry pairs = (Map.Entry) it.next();

            int start = sb.indexOf( pairs.getKey().toString() );

            while( start > -1 && --recurrancyChecker > 0 )
            {
                int length = pairs.getKey().toString().length();
                sb.replace( start, start + length, pairs.getValue().toString() );
                start = sb.indexOf( pairs.getKey().toString() );
                tagFound = true;
            }
        }
    }
    while( tagFound && --recurrancyChecker > 0 );
    return sb.toString();
}

Otros consejos

Básicamente, desea copiar la ejecución de Matcher.replaceAll () así:

public static String replaceTags(String message, Map<String, String> tags) {
  Pattern p = Pattern.compile("#(\\w+)#");
  Matcher m = p.matcher(message);
  boolean result = m.find();
  if (result) {
    StringBuffer sb = new StringBuffer();
    do {
      m.appendReplacement(sb, tags.containsKey(m.group(1) ? tags.get(m.group(1)) : "");
      result = m.find();
    } while (result);
    m.appendTail(sb);
    message = sb.toString();
  }
  return message;
}

Nota: he hecho una suposición sobre la etiqueta válida (a saber, \ w en la expresión regular). Deberá atender esto para lo que es realmente válido (por ejemplo, " # ([\ w _] +) # ").

También asumí que las etiquetas de arriba se ven algo así como:

Map<String, String> tags = new HashMap<String, String>();
tags.add("firstName", "Skippy");

y no:

tags.add("#firstName#", "Skippy");

Si el segundo es correcto, deberás ajustarlo en consecuencia.

Este método hace exactamente una pasada a través de la cadena del mensaje para que no sea mucho más eficiente que esto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top