java - swagger2 - swagger gradle spring boot
Convertir lista<Integer> a List<String> (19)
Tengo una lista de enteros, List<Integer>
y me gustaría convertir todos los objetos enteros en Strings, terminando así con una nueva List<String>
.
Naturalmente, podría crear un nuevo List<String>
y un bucle a través de la lista que llama a String.valueOf()
para cada entero, pero me preguntaba si habría una mejor forma de hacerlo (léase: más automática ).
No vi ninguna solución que siga el principio de la complejidad del espacio. Si la lista de enteros tiene una gran cantidad de elementos, entonces es un gran problema.
It will be really good to remove the integer from the List<Integer> and free
the space, once it''s added to List<String>.
Podemos usar el iterador para lograr lo mismo.
List<Integer> oldList = new ArrayList<>();
oldList.add(12);
oldList.add(14);
.......
.......
List<String> newList = new ArrayList<String>(oldList.size());
Iterator<Integer> itr = oldList.iterator();
while(itr.hasNext()){
newList.add(itr.next().toString());
itr.remove();
}
@Jonathan: Podría estar equivocado, pero creo que String.valueOf () en este caso llamará a la función String.valueOf (Object) en lugar de obtener el encasillado en String.valueOf (int). String.valueOf (Object) simplemente devuelve "null" si es nulo o llama a Object.toString () si no es nulo, lo que no debería involucrar el boxeo (aunque obviamente implica la creación de instancias de nuevos objetos de cadena).
A las personas preocupadas por el "boxeo" en la respuesta de jsight: no hay ninguna. String.valueOf(Object)
se usa aquí, y nunca se realiza unboxing to int
.
Si usa Integer.toString()
o String.valueOf(Object)
depende de cómo quiera manejar posibles nulos. ¿Desea lanzar una excepción (probablemente), o tiene cadenas "nulas" en su lista (tal vez)? Si el primero, ¿quieres lanzar una NullPointerException
o algún otro tipo?
Además, una pequeña falla en la respuesta de jsight: List
es una interfaz, no puedes usar el nuevo operador en ella. Probablemente usaría java.util.ArrayList
en este caso, especialmente dado que sabemos por adelantado cuánto tiempo será la lista.
Aquí hay una solución de una línea sin hacer trampa con una biblioteca que no sea JDK.
List<String> strings = Arrays.asList(list.toString().replaceAll("//[(.*)//]", "$1").split(", "));
Creo que usar Object.toString () para cualquier fin que no sea la depuración es probablemente una idea realmente mala, aunque en este caso los dos son funcionalmente equivalentes (suponiendo que la lista no tenga nulos). Los desarrolladores son libres de cambiar el comportamiento de cualquier método toString () sin ninguna advertencia, incluidos los métodos toString () de cualquier clase en la biblioteca estándar.
Ni siquiera se preocupe por los problemas de rendimiento causados por el proceso de boxeo / desempaquetado. Si el rendimiento es crítico, simplemente use una matriz. Si es realmente crítico, no use Java. Tratar de ser más listo que la JVM solo conducirá a un dolor de corazón.
En lugar de usar String.valueOf usaría .toString (); evita parte del auto boxeo descrito por @ johnathan.holland
El javadoc dice que valueOf devuelve lo mismo que Integer.toString ().
List<Integer> oldList = ...
List<String> newList = new ArrayList<String>(oldList.size());
for (Integer myInt : oldList) {
newList.add(myInt.toString());
}
Esto es algo tan básico que hacer que no utilizaría una biblioteca externa (causará una dependencia en su proyecto que probablemente no necesite).
Tenemos una clase de métodos estáticos específicamente diseñados para hacer este tipo de trabajos. Debido a que el código para esto es tan simple, dejamos que Hotspot haga la optimización por nosotros. Esto parece ser un tema recientemente en mi código: escriba un código muy simple (sencillo) y deje que Hotspot haga su magia. Raramente tenemos problemas de rendimiento con códigos como este: cuando llega una nueva versión de VM, obtienes todos los beneficios de velocidad extra, etc.
Por mucho que ame las colecciones de Yakarta, no admiten Generics y usan 1.4 como LCD. ¡Tengo dudas sobre las Colecciones de Google porque están enumeradas como nivel de asistencia Alfa!
Hasta donde yo sé, iterar y crear instancias es la única forma de hacerlo. Algo así como (para otros, ayuda potencial, ya que estoy seguro de que sabes cómo hacerlo):
List<Integer> oldList = ...
/* Specify the size of the list up front to prevent resizing. */
List<String> newList = new ArrayList<String>(oldList.size())
for (Integer myInt : oldList) {
newList.add(String.valueOf(myInt));
}
La fuente de String.valueOf muestra esto:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
No es que importe mucho, pero usaría toString.
Lo que estás haciendo está bien, pero si sientes la necesidad de ''Java-it-up'' podrías usar un Transformer y el método de recopilación de Apache Commons , por ejemplo:
public class IntegerToStringTransformer implements Transformer<Integer, String> {
public String transform(final Integer i) {
return (i == null ? null : i.toString());
}
}
..y entonces..
CollectionUtils.collect(
collectionOfIntegers,
new IntegerToStringTransformer(),
newCollectionOfStrings);
No es Java central, y no está genérico, pero la popular biblioteca de colecciones comunes de Jakarta tiene algunas abstracciones útiles para este tipo de tareas. Específicamente, eche un vistazo a los métodos de recolección en
Algo a considerar si ya está utilizando las colecciones de commons en su proyecto.
No puedes evitar la "sobrecarga del boxeo"; Los contenedores genéricos falsos de Java solo pueden almacenar Objetos, por lo que tus datos deben estar encuadrados en Enteros. En principio, podría evitar el downcast de Object a Integer (ya que no tiene sentido, porque Object es lo suficientemente bueno para String.valueOf y Object.toString), pero no sé si el compilador es lo suficientemente inteligente como para hacerlo. La conversión de String a Object debería ser más o menos nula, así que no me inclinaría a preocuparme por eso.
Otra solución usando Guava y Java 8
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<String> strings = Lists.transform(numbers, number -> String.valueOf(number));
Solo por diversión, una solución que utiliza el framework jsr166y fork-join que debería tener JDK7.
import java.util.concurrent.forkjoin.*;
private final ForkJoinExecutor executor = new ForkJoinPool();
...
List<Integer> ints = ...;
List<String> strs =
ParallelArray.create(ints.size(), Integer.class, executor)
.withMapping(new Ops.Op<Integer,String>() { public String op(Integer i) {
return String.valueOf(i);
}})
.all()
.asList();
(Descargo de responsabilidad: no compilado. La especificación no está finalizada, etc.)
Es improbable que esté en JDK7, hay un poco de inferencia de tipo y azúcar sintáctico para hacer que la llamada conMapeo sea menos detallada:
.withMapping(#(Integer i) String.valueOf(i))
Solo quería intervenir con una solución orientada a objetos para el problema.
Si modela objetos de dominio, entonces la solución está en los objetos de dominio. El dominio aquí es una lista de enteros para los cuales queremos valores de cadena.
La forma más fácil sería no convertir la lista en absoluto.
Dicho esto, para convertir sin convertir, cambie la lista original de Entero a Lista de valor, donde el valor se ve más o menos así ...
class Value {
Integer value;
public Integer getInt()
{
return value;
}
public String getString()
{
return String.valueOf(value);
}
}
Esto será más rápido y ocupará menos memoria que copiar la Lista.
¡Buena suerte!
Solución para Java 8. Un poco más largo que el de Guava, pero al menos no tiene que instalar una biblioteca.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
//...
List<Integer> integers = Arrays.asList(1, 2, 3, 4);
List<String> strings = integers.stream().map(Object::toString)
.collect(Collectors.toList());
Una respuesta solo para expertos:
List<Integer> ints = ...;
String all = new ArrayList<Integer>(ints).toString();
String[] split = all.substring(1, all.length()-1).split(", ");
List<String> strs = Arrays.asList(split);
Utilizando Google Collections de Guava-Project , puede usar el método de transform
en la clase Lists
import com.google.common.collect.Lists;
import com.google.common.base.Functions
List<Integer> integers = Arrays.asList(1, 2, 3, 4);
List<String> strings = Lists.transform(integers, Functions.toStringFunction());
La List
devuelta por la transform
es una vista en la lista de respaldo: la transformación se aplicará a cada acceso a la lista transformada.
Tenga en cuenta que Functions.toStringFunction()
lanzará una NullPointerException
cuando se aplica a null, por lo tanto, úsela solo si está seguro de que su lista no contendrá null.
Lambdaj permite hacer eso de una manera muy simple y legible. Por ejemplo, suponiendo que tiene una lista de Entero y desea convertirlos en la representación de Cadena correspondiente, podría escribir algo así;
List<Integer> ints = asList(1, 2, 3, 4);
Iterator<String> stringIterator = convertIterator(ints, new Converter<Integer, String> {
public String convert(Integer i) { return Integer.toString(i); }
}
Lambdaj aplica la función de conversión solo mientras itera sobre el resultado.