Mientras trabajaba en una aplicación Java, recientemente necesité armar una lista de valores delimitados por comas para pasar a otro servicio web sin saber cuántos elementos habría de antemano. Lo mejor que se me ocurrió en la cabeza fue algo como esto:
public String appendWithDelimiter( String original, String addition, String delimiter ) {
if ( original.equals( "" ) ) {
return addition;
} else {
return original + delimiter + addition;
}
}
String parameterString = "";
if ( condition ) parameterString = appendWithDelimiter( parameterString, "elementName", "," );
if ( anotherCondition ) parameterString = appendWithDelimiter( parameterString, "anotherElementName", "," );
Me doy cuenta de que esto no es particularmente eficiente, ya que se están creando cadenas por todas partes, pero estaba buscando más claridad que optimización.
En Ruby, puedo hacer algo como esto, que se siente mucho más elegante:
parameterArray = [];
parameterArray << "elementName" if condition;
parameterArray << "anotherElementName" if anotherCondition;
parameterString = parameterArray.join(",");
Pero como Java carece de un comando de unión, no pude encontrar nada equivalente.
Entonces, ¿cuál es la mejor manera de hacer esto en Java?
Respuestas:
Pre Java 8:
Aquí, Commons Lang de Apache es tu amigo: proporciona un método de unión muy similar al que te refieres en Ruby:
StringUtils.join(java.lang.Iterable,char)
Java 8:
Java 8 proporciona la unión fuera de la caja mediante
StringJoiner
yString.join()
. Los fragmentos a continuación muestran cómo puede usarlos:StringJoiner
String.join(CharSequence delimiter, CharSequence... elements))
String.join(CharSequence delimiter, Iterable<? extends CharSequence> elements)
fuente
Podría escribir un pequeño método de utilidad de estilo de unión que funcione en java.util.Lists
Luego úsalo así:
fuente
List<String>
tu inicializadorIterator<?>
y tener el mismo efecto?En el caso de Android, la clase StringUtils de commons no está disponible, así que para esto utilicé
http://developer.android.com/reference/android/text/TextUtils.html
fuente
La biblioteca de guayabas de Google tiene com.google.common.base.Joiner clase que ayuda a resolver tales tareas.
Muestras:
Aquí hay un artículo sobre las utilidades de cuerda de Guava .
fuente
En Java 8 puedes usar
String.join()
:También eche un vistazo a esta respuesta para un ejemplo de Stream API.
fuente
Puedes generalizarlo, pero no hay unión en Java, como bien dices.
Esto podría funcionar mejor.
fuente
Iterable<String>
y solo use el hecho de que puede iterar sobre él. En su ejemplo, no necesita la cantidad de elementos en la colección, por lo que esto es aún más general.StringBuilder
en su lugar. Son idénticos, excepto queStringBuffer
proporcionan seguridad innecesaria de roscas. ¿Alguien puede editarlo?isEmpty()
método, use elnext()
método en su lugaren Java 8 puedes hacer esto como:
si la lista tiene valores nulos, puede usar:
También admite prefijo y sufijo:
fuente
Utilice un enfoque basado en
java.lang.StringBuilder
! ("Una secuencia mutable de caracteres").Como mencionó, todas esas concatenaciones de cadenas están creando cadenas por todas partes.
StringBuilder
No haré eso.¿Por qué en
StringBuilder
lugar deStringBuffer
? Desde elStringBuilder
javadoc:fuente
Yo usaría Google Collections. Hay una bonita instalación de Join.
http://google-collections.googlecode.com/svn/trunk/javadoc/index.html?com/google/common/base/Join.html
Pero si quisiera escribirlo solo,
Creo que funciona mejor con una colección de objetos, ya que ahora no tienes que convertir tus objetos en cadenas antes de unirte a ellos.
fuente
La clase StringUtils de Apache commons tiene un método de unión.
fuente
Java 8
fuente
Puede usar el
StringBuilder
tipo de Java para esto. También existeStringBuffer
, pero contiene lógica de seguridad de hilo adicional que a menudo es innecesaria.fuente
Y uno mínimo (si no desea incluir Apache Commons o Gauva en las dependencias del proyecto solo por unir cadenas)
fuente
Use StringBuilder y clase
Separator
El separador envuelve un delimitador. El separador es devuelto por Separator's
toString
método , a menos que en la primera llamada que devuelva la cadena vacía!Código fuente para clase
Separator
fuente
Separator
para que use un enStringBuilder
lugar de concatenarStrings
?Separator
solo devuelve el delimitador, no concatena la cadena en sí.Separator
? ¿Por qué no usar una cadena simple ...?¿Por qué no escribir su propio método join ()? Tomaría como parámetros la colección de cadenas y un delimitador de cadena. Dentro del método, recorra la colección y construya su resultado en un StringBuffer.
fuente
Si está utilizando Spring MVC, puede intentar seguir los siguientes pasos.
Resultará a
a,b,c
fuente
Si está utilizando Eclipse Collections , puede usar
makeString()
oappendString()
.makeString()
devuelve unaString
representación, similar atoString()
.Tiene tres formas
makeString(start, separator, end)
makeString(separator)
los valores predeterminados comienzan y terminan en cadenas vacíasmakeString()
el separador predeterminado es", "
(coma y espacio)Ejemplo de código:
appendString()
es similar amakeString()
, pero se agrega a unAppendable
(me gustaStringBuilder
) y esvoid
. Tiene las mismas tres formas, con un primer argumento adicional, el Appendable.Si no puede convertir su colección a un tipo de Colecciones Eclipse, simplemente adáptela con el adaptador correspondiente.
Nota: Soy un committer para las colecciones de Eclipse.
fuente
Tipo nativo de Java 8
Objeto personalizado de Java 8:
fuente
Probablemente debería usar a
StringBuilder
con elappend
método para construir su resultado, pero de lo contrario, esta es una solución tan buena como la que Java tiene para ofrecer.fuente
¿Por qué no haces en Java lo mismo que haces en ruby, que es crear la cadena separada por delimitador solo después de haber agregado todas las piezas a la matriz?
Es posible que desee mover ese bucle for en un método auxiliar separado, y también usar StringBuilder en lugar de StringBuffer ...
Editar : se arregló el orden de los anexos.
fuente
Con Java 5 variables args, por lo que no tiene que meter todas sus cadenas en una colección o matriz explícitamente:
fuente
Para aquellos que están en un contexto de primavera, sus StringUtils clase es útil:
Hay muchos atajos útiles como:
y muchos otros.
Esto puede ser útil si aún no está utilizando Java 8 y ya se encuentra en un contexto Spring.
Lo prefiero contra Apache Commons (aunque también es muy bueno) para el soporte de la Colección, que es más fácil de esta manera:
fuente
Puedes probar algo como esto:
fuente
Entonces, básicamente, algo como esto:
fuente
No sé si esto realmente es mejor, pero al menos está usando StringBuilder, que puede ser un poco más eficiente.
A continuación se muestra un enfoque más genérico si puede crear la lista de parámetros ANTES de delimitar cualquier parámetro.
fuente
Su enfoque no es tan malo, pero debe usar un StringBuffer en lugar de usar el signo +. El + tiene la gran desventaja de que se está creando una nueva instancia de String para cada operación. Cuanto más larga sea tu cuerda, mayor será la sobrecarga. Entonces, usar un StringBuffer debería ser la forma más rápida:
Una vez que haya terminado de crear su cadena, simplemente llame a toString () en el StringBuffer devuelto.
fuente
En lugar de usar la concatenación de cadenas, debe usar StringBuilder si su código no está enhebrado, y StringBuffer si lo está.
fuente
Estás haciendo esto un poco más complicado de lo que tiene que ser. Comencemos con el final de su ejemplo:
Con el pequeño cambio de usar un StringBuilder en lugar de un String, esto se convierte en:
Cuando haya terminado (supongo que también debe verificar algunas otras condiciones), solo asegúrese de eliminar la coma de cola con un comando como este:
Y finalmente, obtén la cuerda que deseas con
También puede reemplazar el "," en la segunda llamada para agregar con una cadena de delimitador genérico que se puede establecer en cualquier cosa. Si tiene una lista de cosas que sabe que necesita agregar (sin condiciones), puede poner este código dentro de un método que tome una lista de cadenas.
fuente
fuente
Entonces, un par de cosas que puede hacer para tener la sensación de que parece que está buscando:
1) Extienda la clase Lista y agregue el método de unión. El método de combinación simplemente haría el trabajo de concatenar y agregar el delimitador (que podría ser un parámetro para el método de combinación)
2) Parece que Java 7 va a agregar métodos de extensión a Java, lo que le permite adjuntar un método específico a una clase: para que pueda escribir ese método de unión y agregarlo como un método de extensión a List o incluso a Colección.
La solución 1 es probablemente la única realista, ahora, ya que Java 7 aún no está disponible :) Pero debería funcionar bien.
Para usar ambos, simplemente agrega todos tus elementos a la Lista o Colección como de costumbre, y luego llamas al nuevo método personalizado para 'unirlos'.
fuente