¿Cómo convertir int [] en List <Integer> en Java?

382

¿Cómo se convierte int[]en List<Integer>en Java?

Por supuesto, estoy interesado en cualquier otra respuesta que no sea hacerlo en un bucle, elemento por elemento. Pero si no hay otra respuesta, elegiré esa como la mejor para mostrar el hecho de que esta funcionalidad no es parte de Java.

pupeno
fuente
Podemos hacer uso de IntStream.Of (array) .collect (Collectors.toList)
Saroj Kumar Sahoo

Respuestas:

259

No hay un atajo para convertir de int[]a List<Integer>ya Arrays.asListque no se ocupa del boxeo y solo creará uno List<int[]>que no es lo que desea. Tienes que hacer un método de utilidad.

int[] ints = {1, 2, 3};
List<Integer> intList = new ArrayList<Integer>(ints.length);
for (int i : ints)
{
    intList.add(i);
}
willcodejavaforfood
fuente
32
Es mejor inicializar la lista con el tamaño de la matriz
David Rabinowitz el
110
para (int i: ints) intList.add (i);
Stephen Denne el
18
@willcodejavaforfood - David quiere decir que esto es mejor: nueva ArrayList <Integer> (ints.length);
Stephen Denne el
12
@willcodejavaforfood: declarar el tamaño de ArrayList cuando se está construyendo evitará que tenga que redimensionarse internamente después de agregar una cierta cantidad. No estoy seguro si el beneficio es pequeño, pero definitivamente hay un beneficio.
Grundlefleck
10
new ArrayList<Integer>() {{ for (int i : ints) add(i); }}
saka1029
350

Corrientes

En Java 8 puedes hacer esto

int[] ints = {1,2,3};
List<Integer> list = Arrays.stream(ints).boxed().collect(Collectors.toList());
mikeyreilly
fuente
21
Equivalente a: Arrays.stream (ints) .boxed (). Collect (Collectors.toList ());
njfrost 01 de
44
@njfrost Tienes razón e IntStream.of solo llama a Arrays.stream, así que he mejorado la respuesta siguiendo tu sugerencia
mikeyreilly
Por alguna razón, esto no parece devolver el tipo de resultado esperado en Android Studio (funciona en eclipse). Dice, la lista esperada <Integer> encontró la lista <Objeto>.
Eugenio López el
Parece limpio y conciso, pero cuando utilicé esto en lugar de la solución básica proporcionada por @willcodejavaforfood en leetcode, el rendimiento del programa se degradó en términos de memoria y tiempo de ejecución
chitresh sirohi
@chitreshsirohi eso se debe a que las funciones lambda utilizadas dentro de las transmisiones dan como resultado que Java cree algunas clases anónimas.
Ashvin Sharma
175

También de las bibliotecas de guayaba ... com.google.common.primitives.Ints:

List<Integer> Ints.asList(int...)
louisgab
fuente
11
Esta debería ser la respuesta correcta. Vea la segunda oración de la pregunta: "Por supuesto, estoy interesado en cualquier otra respuesta que no sea hacerlo en un ciclo, elemento por elemento".
josketres
¡Gracias, gracias, gracias! También funciona para Longs.asList (long ...).
craastad
2
Hay algunas sutilezas aquí. La lista devuelta utiliza la matriz proporcionada como almacén de respaldo, por lo que no debe mutar la matriz. La lista tampoco garantiza la identidad de los objetos Integer contenidos. Es decir, el resultado de list.get (0) == list.get (0) no está especificado.
pburka
1
Tenga cuidado con el recuento de referencias de métodos en Android al agregar bibliotecas. Buen hallazgo sin embargo.
milosmns
95

Arrays.asList no funcionará como algunas de las otras respuestas esperan.

Este código no creará una lista de 10 enteros. Imprimirá 1 , no 10 :

int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
List lst = Arrays.asList(arr);
System.out.println(lst.size());

Esto creará una lista de enteros:

List<Integer> lst = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

Si ya tiene la matriz de entradas, no hay una forma rápida de convertir, es mejor que tenga el ciclo.

Por otro lado, si su matriz tiene Objetos, no primitivos, Arrays.asList funcionará:

String str[] = { "Homer", "Marge", "Bart", "Lisa", "Maggie" };
List<String> lst = Arrays.asList(str);
Leonel
fuente
2
Tenga en cuenta que esa lista es inmutable
Danielson
51

Agregaré otra respuesta con un método diferente; sin bucle, sino una clase anónima que utilizará las características de autoboxing:

public List<Integer> asList(final int[] is)
{
    return new AbstractList<Integer>() {
            public Integer get(int i) { return is[i]; }
            public int size() { return is.length; }
    };
}
Christoffer
fuente
1
+1 es más corto que el mío, pero el mío funciona para todos los tipos primitivos
dfa
55
Si bien es más rápido y usa menos memoria que crear una ArrayList, la compensación es List.add () y List.remove () no funcionan.
Stephen Denne el
3
Me gusta bastante esta solución para matrices grandes con patrones de acceso dispersos, pero para elementos a los que se accede con frecuencia daría lugar a muchas instancias innecesarias de Integer (por ejemplo, si accedió al mismo elemento 100 veces). También necesitaría definir Iterator y ajustar el valor de retorno en Collections.unmodifiableList.
Adamski el
@Christoffer gracias. He agregado el setmétodo y ahora incluso puedo ordenar la matriz ...
freedev
39

El fragmento de código más pequeño sería:

public List<Integer> myWork(int[] array) {
    return Arrays.asList(ArrayUtils.toObject(array));
}

donde ArrayUtils proviene de commons-lang :)

Kannan Ekanath
fuente
99
Solo tenga ArrayUtilsen cuenta que es una biblioteca relativamente grande para una aplicación de Android
msysmilu
Aquí se describe la operación opuesta: stackoverflow.com/a/960507/1333157 ArrayUtils.toPrimitive(...) es la clave.
ZeroOne
26

En Java 8 con transmisión:

int[] ints = {1, 2, 3};
List<Integer> list = new ArrayList<Integer>();
Collections.addAll(list, Arrays.stream(ints).boxed().toArray(Integer[]::new));

o con coleccionistas

List<Integer> list =  Arrays.stream(ints).boxed().collect(Collectors.toList());
usuario2037659
fuente
3
¿Por qué no simplemente usar un colector?
Assylias
19

En Java 8:

int[] arr = {1,2,3};
IntStream.of(arr).boxed().collect(Collectors.toList());
Neeraj
fuente
16

Si está utilizando Java 8, podemos utilizar la API de transmisión para convertirlo en una lista.

List<Integer> list = Arrays.stream(arr)     // IntStream 
                                .boxed()        // Stream<Integer>
                                .collect(Collectors.toList());

También puede usar IntStream para convertir también.

List<Integer> list = IntStream.of(arr) // return Intstream
                                    .boxed()        // Stream<Integer>
                                    .collect(Collectors.toList());

Hay otras bibliotecas externas como guayaba y apache commons también disponibles para convertirlo.

salud.

Mukesh Kumar Gupta
fuente
11

También vale la pena revisar este informe de error , que se cerró con el motivo "No es un defecto" y el siguiente texto:

"El autoboxing de arreglos completos no es un comportamiento especificado, por una buena razón. Puede ser prohibitivamente costoso para arreglos grandes".

Adamski
fuente
7

probar esta clase:

class PrimitiveWrapper<T> extends AbstractList<T> {

    private final T[] data;

    private PrimitiveWrapper(T[] data) {
        this.data = data; // you can clone this array for preventing aliasing
    }

    public static <T> List<T> ofIntegers(int... data) {
        return new PrimitiveWrapper(toBoxedArray(Integer.class, data));
    }

    public static <T> List<T> ofCharacters(char... data) {
        return new PrimitiveWrapper(toBoxedArray(Character.class, data));
    }

    public static <T> List<T> ofDoubles(double... data) {
        return new PrimitiveWrapper(toBoxedArray(Double.class, data));
    }  

    // ditto for byte, float, boolean, long

    private static <T> T[] toBoxedArray(Class<T> boxClass, Object components) {
        final int length = Array.getLength(components);
        Object res = Array.newInstance(boxClass, length);

        for (int i = 0; i < length; i++) {
            Array.set(res, i, Array.get(components, i));
        }

        return (T[]) res;
    }

    @Override
    public T get(int index) {
        return data[index];
    }

    @Override
    public int size() {
        return data.length;
    }
}

caso de prueba:

List<Integer> ints = PrimitiveWrapper.ofIntegers(10, 20);
List<Double> doubles = PrimitiveWrapper.ofDoubles(10, 20);
// etc
dfa
fuente
5

El mejor tiro:

**
 * Integer modifiable fix length list of an int array or many int's.
 *
 * @author Daniel De Leon.
 */
public class IntegerListWrap extends AbstractList<Integer> {

    int[] data;

    public IntegerListWrap(int... data) {
        this.data = data;
    }

    @Override
    public Integer get(int index) {
        return data[index];
    }

    @Override
    public Integer set(int index, Integer element) {
        int r = data[index];
        data[index] = element;
        return r;
    }

    @Override
    public int size() {
        return data.length;
    }
}
  • Soporte get and set.
  • Sin memoria de duplicación de datos.
  • No perder el tiempo en bucles.

Ejemplos:

int[] intArray = new int[]{1, 2, 3};
List<Integer> integerListWrap = new IntegerListWrap(intArray);
List<Integer> integerListWrap1 = new IntegerListWrap(1, 2, 3);
Daniel De León
fuente
Me gusta más. Pero todavía usaría guayaba para tener una solución directa :)
dantuch
1

Si está abierto a usar una biblioteca de terceros, esto funcionará en Eclipse Collections :

int[] a = {1, 2, 3};
List<Integer> integers = IntLists.mutable.with(a).collect(i -> i);
Assert.assertEquals(Lists.mutable.with(1, 2, 3), integers);

Nota: Soy un committer para Eclipse Collections .

Donald Raab
fuente
1
   /* Integer[] to List<Integer> */



        Integer[] intArr = { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
        List<Integer> arrList = new ArrayList<>();
        arrList.addAll(Arrays.asList(intArr));
        System.out.println(arrList);


/* Integer[] to Collection<Integer> */


    Integer[] intArr = { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
    Collection<Integer> c = Arrays.asList(intArr);
Uddhav Gautam
fuente
1

¿Qué hay de esto?

int[] a = {1,2,3}; Integer[] b = ArrayUtils.toObject(a); List<Integer> c = Arrays.asList(b);

humilde
fuente
1

Aquí hay una solución:

int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

Integer[] iArray = Arrays.stream(array).boxed().toArray(Integer[]::new);
System.out.println(Arrays.toString(iArray));

List<Integer> list = new ArrayList<>();
Collections.addAll(list, iArray);
System.out.println(list);

Salida:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Amitabha Roy
fuente
1

Aquí hay otra posibilidad, de nuevo con Java 8 Streams:

void intArrayToListOfIntegers(int[] arr, List<Integer> list) {
    IntStream.range(0, arr.length).forEach(i -> list.add(arr[i]));
}
Koray Tugay
fuente
0

Aquí hay una forma genérica de convertir la matriz a ArrayList

<T> ArrayList<T> toArrayList(Object o, Class<T> type){
    ArrayList<T> objects = new ArrayList<>();
    for (int i = 0; i < Array.getLength(o); i++) {
        //noinspection unchecked
        objects.add((T) Array.get(o, i));
    }
    return objects;
}

Uso

ArrayList<Integer> list = toArrayList(new int[]{1,2,3}, Integer.class);
Ilya Gazman
fuente
0
int[] arr = { 1, 2, 3, 4, 5 };

List<Integer> list = Arrays.stream(arr)     // IntStream
                            .boxed()        // Stream<Integer>
                            .collect(Collectors.toList());

ver esto

hamidreza75
fuente