Tengo un ArrayList
que quiero generar completamente como una cadena. Esencialmente quiero generarlo en orden usando el toString
de cada elemento separado por pestañas. ¿Hay alguna forma rápida de hacer esto? Puede recorrerlo (o eliminar cada elemento) y concatenarlo en una Cadena, pero creo que esto será muy lento.
353
Respuestas:
Básicamente, usar un bucle para iterar sobre
ArrayList
es la única opción:NO use este código, continúe leyendo hasta el final de esta respuesta para ver por qué no es deseable y qué código debe usarse en su lugar:
De hecho, una concatenación de cadenas estará bien, ya que el
javac
compilador optimizará la concatenación de cadenas como una serie deappend
operaciones deStringBuilder
todos modos. Aquí hay una parte del desmontaje del bytecode delfor
bucle del programa anterior:Como se puede ver, el compilador optimiza ese ciclo mediante el uso de a
StringBuilder
, por lo que el rendimiento no debería ser una gran preocupación.(OK, en una segunda mirada,
StringBuilder
se está instanciando el en cada iteración del bucle, por lo que puede que no sea el código de bytes más eficiente. La creación de instancias y el uso de un explícitoStringBuilder
probablemente produciría un mejor rendimiento).De hecho, creo que tener cualquier tipo de salida (ya sea en el disco o en la pantalla) será al menos un orden de magnitud más lento que tener que preocuparse por el rendimiento de las concatenaciones de cadenas.
Editar: Como se señaló en los comentarios, la optimización del compilador anterior está creando una nueva instancia de
StringBuilder
cada iteración. (Lo cual he notado anteriormente).La técnica más optimizada para usar será la respuesta de Paul Tomblin , ya que solo crea una instancia de un
StringBuilder
objeto fuera delfor
bucle.Reescribiendo el código anterior para:
Solo creará
StringBuilder
una instancia fuera del bucle y solo realizará las dos llamadas alappend
método dentro del bucle, como se evidencia en este código de bytes (que muestra la instanciaciónStringBuilder
y el bucle):Entonces, de hecho, la optimización de la mano debería tener un mejor rendimiento, ya que el interior del
for
bucle es más corto y no hay necesidad de crear una instanciaStringBuilder
en cada iteración.fuente
Java
o Geewax paraAndroid
En Java 8 o posterior:
En caso de
list
que no sea de tipo String, se puede usar un recopilador de unión:fuente
Si está haciendo esto en Android, hay una buena utilidad para esto llamada TextUtils que tiene un
.join(String delimiter, Iterable)
método.Obviamente no uso mucho fuera de Android, pero pensé que lo agregaría a este hilo ...
fuente
TextUtils.join
toma unObject[]
, supongo que está llamandotoString()
a cada token. ¿PatientDetails
ImplementatoString()
? Si eso no resuelve el problema, puede estar atrapado haciendo algo con laSeparator
clase.org.apache.lang3.StringUtils
hace prácticamente lo mismo, por lo que su respuesta me fue de mucha utilidad fuera de Android :)Descargue Apache Commons Lang y use el método
Puede implementarlo usted mismo, por supuesto, pero su código está completamente probado y es probablemente la mejor implementación posible.
Soy un gran admirador de la biblioteca Apache Commons y también creo que es una gran adición a la Biblioteca estándar de Java.
fuente
StringUtils.join(list.toArray(),"\t")
Esta es una pregunta bastante antigua, pero creo que también podría agregar una respuesta más moderna: use la
Joiner
clase de Guava :fuente
Cambiar la Lista a una Cadena legible y significativa es realmente una pregunta común que todos pueden encontrar.
Caso 1 . Si tiene StringUtils de apache en su ruta de clase (como de rogerdpack y Ravi Wallau):
Caso 2 . Si solo desea utilizar formas de JDK (7):
Simplemente nunca construya ruedas usted mismo, no use el bucle para esta tarea de una línea.
fuente
Arrays.toString(myList.toArray())
- la solución más fácil y sencillaArrays.toString(list.toArray())
Es fácil de escribir, pero altamente ineficiente.Si estaba buscando una línea rápida, a partir de Java 5 puede hacer esto:
Además, si su propósito es imprimir el contenido y está menos preocupado por el "\ t", simplemente puede hacer esto:
que devuelve una cadena como
Si tiene una matriz (no ArrayList), puede lograr lo mismo de esta manera:
fuente
m
hogares enn
ciudades de losx
estados, dirías que esO(mnx)
oO(n^3)
, pero puedo reformularlo para decir "busca a esta persona en este país", y me lo dirías de inmediatoO(n)
. Además de eso, todos los algoritmos aquí son generalmenteO(n)
, no hay bucle dentro de un bucle.Recorrerlo y llamar a String. No hay una forma mágica, y si la hubiera, ¿qué crees que estaría haciendo bajo las sábanas además de recorrerla? Casi la única microoptimización sería usar StringBuilder en lugar de String, e incluso eso no es una gran victoria: la concatenación de cadenas se convierte en StringBuilder debajo de las cubiertas, pero al menos si lo escribe de esa manera, puede ver lo que está sucediendo.
fuente
La mayoría de los proyectos Java a menudo tienen apache-commons lang disponibles. Los métodos StringUtils.join () son muy agradables y tienen varios sabores para satisfacer casi todas las necesidades.
fuente
join(...)
método tiene variantes para matrices y colecciones.Android tiene una clase TextUtil que puede usar http://developer.android.com/reference/android/text/TextUtils.html
fuente
Para este caso de uso simple, simplemente puede unir las cadenas con una coma. Si usa Java 8:
de lo contrario, commons-lang tiene un método join ():
fuente
Una forma elegante de lidiar con los caracteres de separación final es usar Class Separator
El método toString de Class Separator devuelve el separador, a excepción de la primera llamada. Por lo tanto, imprimimos la lista sin separadores iniciales (o en este caso) finales.
fuente
En Java 8 es simple. Vea el ejemplo para la lista de enteros:
O versión multilínea (que es más fácil de leer):
Actualización: una versión más corta
fuente
filter
. Al final, es mucho más fácil para mí leer el código.String
. Si es una lista deInteger
Es un
O(n)
algoritmo de cualquier manera (a menos que haya hecho alguna solución de subprocesos múltiples en la que separó la lista en varias sublistas, pero no creo que sea lo que está pidiendo).Simplemente use un
StringBuilder
como a continuación:El
StringBuilder
va a ser mucho más rápido que la concatenación de cadenas, ya que no se volverá a instancias de unString
objeto en cada una concatenación.fuente
En caso de que esté en Android y aún no esté usando Jack (por ejemplo, porque todavía no tiene soporte para Instant Run), y si desea tener más control sobre el formato de la cadena resultante (por ejemplo, le gustaría usar el carácter de nueva línea como el divisor de elementos), y al usar / querer usar la biblioteca StreamSupport (para usar secuencias en Java 7 o versiones anteriores del compilador), podría usar algo como esto (pongo este método en mi clase ListUtils):
Y, por supuesto, asegúrese de implementar toString () en la clase de objetos de su lista.
fuente
reduce
es extremadamente ineficiente para la concatenación de cadenas. Debe hacerlo de la manera Java 8return StreamSupport.stream(list).map(Object::toString).collect(joining("\n"))
que usa internamenteStringJoiner
. No hay razón para que no puedas hacer esto con streamsupport también.Optional#get
) si se pasa una lista vacía.Si no desea el último \ t después del último elemento, debe usar el índice para verificar, pero recuerde que esto solo "funciona" (es decir, es O (n)) cuando las listas implementan RandomAccess.
fuente
El siguiente código puede ayudarlo,
Salida:
fuente
Puede que no sea la mejor manera, sino la manera elegante.
Arrays.deepToString (Arrays.asList ("Prueba", "Prueba2")
Salida
[Prueba, Prueba2]
fuente
¿Sería bueno lo siguiente?
fuente
Si está usando Eclipse Collections , puede usar el
makeString()
método.Si puede convertir su
ArrayList
aFastList
, puede deshacerse del adaptador.Nota: Soy un committer para Eclipse Collections.
fuente
Pasa a la
new StringJoiner
secuencia de caracteres que desea utilizar como separador. Si quieres hacer un CSV:new StringJoiner(", ");
fuente
En una línea: de [12,0,1,78,12] a 12 0 1 78 12
fuente
Para separar usando pestañas en lugar de usar println puedes usar print
fuente
Veo algunos ejemplos que dependen de recursos adicionales, pero parece que esta sería la solución más simple: (que es lo que usé en mi propio proyecto) que básicamente se está convirtiendo de una ArrayList a una Array y luego a una Lista .
fuente
Esta es una conversación bastante antigua por ahora y los comunes de Apache ahora están utilizando un StringBuilder internamente: http://commons.apache.org/lang/api/src-html/org/apache/commons/lang/StringUtils.html#line. 3045
Como sabemos, esto mejorará el rendimiento, pero si el rendimiento es crítico, entonces el método utilizado podría ser algo ineficiente. Mientras que la interfaz es flexible y permitirá un comportamiento consistente en diferentes tipos de Colección, es algo ineficiente para las Listas, que es el tipo de Colección en la pregunta original.
Baso esto en que estamos incurriendo en una sobrecarga que evitaríamos simplemente iterando a través de los elementos en un bucle for tradicional. En cambio, hay algunas cosas adicionales que suceden detrás de escena para verificar modificaciones concurrentes, llamadas a métodos, etc. Por otro lado, el bucle for mejorado dará como resultado la misma sobrecarga ya que el iterador se usa en el objeto Iterable (la Lista).
fuente
Puedes usar un Regex para esto. Esto es tan conciso como se pone
fuente
¿Qué tal esta función:
funciona para cualquier tipo de colección ...
fuente