2009-07-02 18 views
218

Come convertire int[] in List<Integer> in Java?Come convertire int [] nella lista <Integer> in Java?

Naturalmente, sono interessato a qualsiasi altra risposta rispetto a farlo in un ciclo, articolo per articolo. Ma se non c'è altra risposta, la sceglierò come la migliore per mostrare il fatto che questa funzionalità non fa parte di Java.

risposta

160

non ci sono scorciatoie per la conversione da int[] a List<Integer> come Arrays.asList non si occupa con la boxe e sarà solo creare un List<int[]> che non è ciò che si desidera. Devi fare un metodo di utilità.

int[] ints = {1, 2, 3}; 
List<Integer> intList = new ArrayList<Integer>(); 
for (int i : ints) 
{ 
    intList.add(i); 
} 
+27

è meglio per inizializzare la lista con la dimensione della matrice –

+0

@ David Rabinowitz - Non so cosa dire a che :) – willcodejavaforfood

+0

Se si insiste per usare l'implementazione di ArrayList, perché non usare solo il costruttore sovraccaricato per fare: nuovo ArrayList (myArray)? –

8

È anche la pena di verificare this bug report, che è stato chiuso con la ragione "Non è un difetto" ed il testo seguente:.

comportamento

"Autoboxing di intere matrici non è specificato, a ragione Può essere proibitivamente costoso per i grandi array ".

52

Arrays.asList non funzionerà come previsto da alcune delle altre risposte.

Questo codice sarà non creare un elenco di 10 numeri interi. Sarà stampata , non :

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

Questo creerà una lista di interi:

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

Se avete già l'array di int, non v'è modo veloce per convertire , stai meglio con il ciclo.

D'altra parte, se la matrice ha oggetti, non primitive in esso, Arrays.asList funzionerà:

String str[] = { "Homer", "Marge", "Bart", "Lisa", "Maggie" }; 
List<String> lst = Arrays.asList(str); 
+2

Bella informazione! –

7

dare una prova di questa classe:

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; 
    } 
} 

TestCase:

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

Aggiungerò un'altra risposta con un metodo diverso; nessun ciclo ma una classe anonima che utilizzerà le caratteristiche 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; } 
    }; 
} 
+1

+1 questo è più corto del mio, ma il mio funziona per tutti i tipi di primitive – dfa

+5

Mentre più veloce e usando meno memoria rispetto alla creazione di un ArrayList, il trade off è List.add() e List.remove() non funzionano. –

+3

Mi piace molto questa soluzione per array di grandi dimensioni con pattern di accesso sparsi, ma per gli elementi di accesso frequente si otterrebbero molte istanze inutili di Integer (ad esempio se si accede allo stesso elemento 100 volte).Inoltre, è necessario definire Iterator e avvolgere il valore restituito in Collections.unmodifiableList. – Adamski

33

Il pezzo più piccolo del codice sarebbe:

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

dove ArrayUtils proviene da commons-lang :)

+6

Basta notare' ArrayUtils' è una libreria relativamente grande per un'app Android – msysmilu

147

anche da guava libraries ... com.google.common.primitives.Ints:

List<Integer> Ints.asList(int...) 
+9

Questa dovrebbe essere la risposta giusta. Vedi la seconda frase della domanda: "Certo, sono interessato a qualsiasi altra risposta che a farlo in un ciclo, articolo per articolo." – josketres

+0

Grazie grazie grazie! Funziona anche per Longs.asList (lungo ...). – craastad

+2

Qui ci sono alcune sottigliezze. L'elenco restituito utilizza l'array fornito come archivio di backup, pertanto non è necessario modificare l'array. L'elenco inoltre non garantisce l'identità degli oggetti interi contenuti. Cioè, il risultato di list.get (0) == list.get (0) non è specificato. – pburka

4

Il colpo migliore:

** 
* 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; 
    } 
} 
  • Supporto ottenere e impostare.
  • Nessuna duplicazione dei dati di memoria.
  • Nessuna perdita di tempo nei loop.

Esempi:

int[] intArray = new int[]{1, 2, 3}; 
List<Integer> integerListWrap = new IntegerListWrap(intArray); 
List<Integer> integerListWrap1 = new IntegerListWrap(1, 2, 3); 
+0

Mi piace di più. Ma userei ancora guava per avere una soluzione immediata :) – dantuch

14

In Java 8 con flusso:

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

o con collettori

List<Integer> list = Arrays.stream(ints).boxed().collect(Collectors.toList()); 
+1

Perché non usare semplicemente un raccoglitore? – assylias

135

in Java 8 è possibile farlo

int[] ints = {1,2,3}; 
List<Integer> list = Arrays.stream(ints).boxed().collect(Collectors.toList()); 
+14

Equivalente a: Arrays.stream (ints) .boxed(). Collect (Collectors.toList()); – njfrost

+0

@njfrost Hai ragione e IntStream.of chiama semplicemente Arrays.stream quindi ho migliorato la risposta seguendo il tuo suggerimento – mikeyreilly

0

Ecco un modo generico per convertire array 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); 
1

Se siete aperti a utilizzare una libreria di terze parti, questo sistema funziona in 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: I am a committer per Eclipse Collections.

0
/* 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); 
3

In Java 8:

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