Come convertire la lista in int [] in Java?


Questo è simile a questa domanda: Come convertire int [] in Integer [] in Java?

Sono nuovo di Java. Come posso convertire un List<Integer> in int[] in Java? Sono confuso perché List.toArray() restituisce effettivamente un Object[], che può essere lanciato su nether Integer[] o int[].

In questo momento sto usando un ciclo per farlo:

int[] toIntArray(List<Integer> list){
  int[] ret = new int[list.size()];
  for(int i = 0;i < ret.length;i++)
    ret[i] = list.get(i);
  return ret;
}

Sono sicuro che c'è un modo migliore per farlo.

Author: Community, 2009-06-07

17 answers

Sfortunatamente, non credo che sia un modo migliore per farlo a causa della natura della gestione di Java di tipi primitivi, boxe, array e generici. In particolare:

  • List<T>.toArray non funzionerà perché non c'è alcuna conversione da Integer a int
  • Non puoi usare intcome argomento di tipo per i generici, quindi dovrebbe essere un metodo specifico di int (o uno che ha usato reflection per fare brutti trucchi).

Credo che ci siano librerie che hanno versioni autogenerate di questo tipo di metodo per tutti i tipi primitivi (cioè c'è un modello che viene copiato per ogni tipo). È brutto, ma è così che ho paura : (

Anche se il Arrays la classe è uscita prima che i generici arrivassero in Java, dovrebbe comunque includere tutti gli orribili sovraccarichi se fosse stata introdotta oggi (supponendo che si desideri utilizzare array primitivi).

 176
Author: Jon Skeet, 2009-06-06 20:28:18

Nessuno ha ancora menzionato i flussi aggiunti in Java 8, quindi eccolo qui:

int[] array = list.stream().mapToInt(i->i).toArray();

Processo di pensiero:

  • semplice Stream#toArray restituisce Object[], quindi non è quello che vogliamo. Inoltre Stream#toArray(IntFunction<A[]> generator) non fa quello che vogliamo perché il tipo generico A non può rappresentare il primitivo int
  • quindi sarebbe bello avere un flusso in grado di gestire il tipo primitivo int, perché il suo metodo toArray molto probabilmente restituirà anche int[] array (restituendo qualcos'altro come Object[] o anche in scatola Integer[] sarebbe innaturale qui). E fortunatamente Java 8 ha tale flusso: IntStream
  • Quindi ora l'unica cosa che dobbiamo capire è come convertire il nostro Stream<Integer> (che verrà restituito da list.stream()) a quello lucido IntStream. Qui il metodo mapToInt viene in soccorso. Tutto quello che dobbiamo fare è fornire una mappatura da Integer a int. Potremmo usare qualcosa come Integer#getValue che restituisce int:

    mapToInt( (Integer i) -> i.intValue())

    (o se qualcuno preferisce mapToInt(Integer::intValue))

    Ma un codice simile può essere generato utilizzando unboxing, poiché il compilatore sa che il risultato di questo lambda deve essere int (lambda in mapToInt è l'implementazione dell'interfaccia ToIntFunction che prevede il corpo per il metodo int applyAsInt(T value) che dovrebbe restituire int).

    Quindi possiamo semplicemente scrivere

    mapToInt((Integer i)->i)

    O più semplice (poiché il tipo Integer i può essere dedotto dal compilatore perché List<Integer>#stream() restituisce Stream<Integer>)

    mapToInt(i -> i)

 414
Author: Pshemo, 2016-03-17 17:16:34

Oltre a Commons Lang, puoi farlo con il metodo di Guava Ints.toArray(Collection<Integer> collection):

List<Integer> list = ...
int[] ints = Ints.toArray(list);

Questo ti evita di dover fare la conversione dell'array intermedio che l'equivalente Commons Lang richiede a te stesso.

 185
Author: ColinD, 2016-05-17 05:35:01

Il modo più semplice per farlo è usare Apache Commons Lang. Ha una comoda classe ArrayUtils che può fare ciò che vuoi. Utilizzare il toPrimitive metodo con il sovraccarico per un array di Integers.

List<Integer> myList;
 ... assign and fill the list
int[] intArray = ArrayUtils.toPrimitive(myList.toArray(new Integer[myList.size()]));

In questo modo non si reinventa la ruota. Commons Lang ha molte cose utili che Java ha lasciato fuori. Sopra, ho scelto di creare un elenco intero della giusta dimensione. È inoltre possibile utilizzare un array intero statico di lunghezza 0 e lasciare che Java allochi un array di destra dimensione:

static final Integer[] NO_INTS = new Integer[0];
   ....
int[] intArray2 = ArrayUtils.toPrimitive(myList.toArray(NO_INTS));
 166
Author: Eddie, 2013-03-14 08:09:35
int[] toIntArray(List<Integer> list)  {
    int[] ret = new int[list.size()];
    int i = 0;
    for (Integer e : list)  
        ret[i++] = e;
    return ret;
}

Leggera modifica al codice per evitare costose indicizzazioni di elenchi (poiché una lista non è necessariamente una ArrayList, ma potrebbe essere una lista collegata, per la quale l'accesso casuale è costoso)

 47
Author: Cheok Yan Cheng, 2018-07-28 05:34:42

Java 8 ci ha dato un modo semplice per farlo tramite stream...

Utilizzando la funzione collections stream() e quindi mappando su ints, otterrai un IntStream. Con IntStream possiamo chiamare toArray () che ci dà int []

int [] ints = list.stream().mapToInt(Integer::intValue).toArray();

A int []

A IntStream

 30
Author: Pumphouse, 2016-09-09 04:30:02

Ecco Java 8 codice a riga singola per questo

public int[] toIntArray(List<Integer> intList){
       return intList.stream().mapToInt(Integer::intValue).toArray();
}
 12
Author: Noor Nawaz, 2016-07-11 10:38:14

Ne butto un altro qui. Ho notato diversi usi di for loops, ma non hai nemmeno bisogno di nulla all'interno del ciclo. Lo dico solo perché la domanda originale stava cercando di trovare un codice meno dettagliato.

int[] toArray(List<Integer> list) {
    int[] ret = new int[ list.size() ];
    int i = 0;
    for( Iterator<Integer> it = list.iterator(); 
         it.hasNext(); 
         ret[i++] = it.next() );
    return ret;
}

Se Java consentiva più dichiarazioni in un ciclo for come fa C++, potremmo fare un ulteriore passo avanti e fare for(int i = 0, Iterator it...

Alla fine però (questa parte è solo la mia opinione), se hai intenzione di avere una funzione o un metodo di aiuto per fare qualcosa per te, basta configurarlo e dimenticarlo. Può essere un one-liner o dieci; se non lo guarderai mai più non saprai la differenza.

 6
Author: Loduwijk, 2015-11-11 15:30:17

Questo semplice ciclo è sempre corretto! nessun bug

  int[] integers = new int[myList.size()];
  for (int i = 0; i < integers.length; i++) {
      integers[i] = myList.get(i);
  }
 6
Author: THANN Phearum, 2016-10-31 08:04:25

Se stai semplicemente mappando un Integer a un intallora dovresti considerare usando il parallelismo, poiché la tua logica di mappatura non si basa su variabili al di fuori del suo ambito.

int[] arr = list.parallelStream().mapToInt(Integer::intValue).toArray();

Basta essere consapevoli di questo

Si noti che il parallelismo non è automaticamente più veloce dell'esecuzione di operazioni in serie, anche se può essere se si dispone di dati e core del processore sufficienti. Mentre le operazioni di aggregazione consentono di implementare più facilmente il parallelismo, è ancora il tuo responsabilità di determinare se l'applicazione è adatta per il parallelismo.


Esistono due modi per mappare gli interi alla loro forma primitiva:

  1. Tramite un ToIntFunction.

    mapToInt(Integer::intValue)
    
  2. Tramite esplicito unboxing con espressione lambda.

    mapToInt(i -> i.intValue())
    
  3. Tramite unboxing implicito (automatico) con espressione lambda.

    mapToInt(i -> i)
    

Data una lista con un valore null

List<Integer> list = Arrays.asList(1, 2, null, 4, 5);

Ecco tre opzioni per gestire null:

  1. Filtra i valori null prima della mappatura.

    int[] arr = list.parallelStream().filter(Objects::nonNull).mapToInt(Integer::intValue).toArray();
    
  2. Associa i valori null a un valore predefinito.

    int[] arr = list.parallelStream().map(i -> i == null ? -1 : i).mapToInt(Integer::intValue).toArray();
    
  3. Gestire null all'interno dell'espressione lambda.

    int[] arr = list.parallelStream().mapToInt(i -> i == null ? -1 : i.intValue()).toArray();
    
 5
Author: Mr. Polywhirl, 2015-11-30 12:54:40
int[] ret = new int[list.size()];       
Iterator<Integer> iter = list.iterator();
for (int i=0; iter.hasNext(); i++) {       
    ret[i] = iter.next();                
}                                        
return ret;                              
 4
Author: gerardw, 2013-09-03 19:08:23

Non c'è davvero alcun modo di "one-lining" ciò che stai cercando di fare perché toArray restituisce un oggetto [] e non puoi lanciare da Object [] a int[] o Integer [] a int []

 3
Author: neesh, 2009-06-06 20:39:03

Prova anche Dollaro (controlla questa revisione):

import static com.humaorie.dollar.Dollar.*
...

List<Integer> source = ...;
int[] ints = $(source).convert().toIntArray();
 3
Author: dfa, 2010-07-05 14:40:20

Con Eclipse Collections , puoi fare quanto segue se hai un elenco di tipo java.util.List<Integer>:

List<Integer> integers = Lists.mutable.with(1, 2, 3, 4, 5);
int[] ints = LazyIterate.adapt(integers).collectInt(i -> i).toArray();

Assert.assertArrayEquals(new int[]{1, 2, 3, 4, 5}, ints);

Se hai già un tipo Eclipse Collections come MutableList, puoi fare quanto segue:

MutableList<Integer> integers = Lists.mutable.with(1, 2, 3, 4, 5);
int[] ints = integers.asLazy().collectInt(i -> i).toArray();

Assert.assertArrayEquals(new int[]{1, 2, 3, 4, 5}, ints);

Nota: sono un committer per le collezioni Eclipse

 2
Author: Donald Raab, 2016-03-01 19:32:47

A partire da java 8 questo può essere facilmente ottenuto usando Stream API

int[] temp =  list.stream().mapToInt(Integer::intValue).toArray();

Se si desidera avere maggiori informazioni su come questo processo è completato id piace reindirizzare a questo link http://www.techiedelight.com/convert-stream-array-java/#2

 2
Author: Milad Masoodi, 2018-08-16 10:07:49

Ti consiglierei di usare List<?> implementazione scheletrica dall'API java collections, sembra essere molto utile in questo caso particolare:

package mypackage;

import java.util.AbstractList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class Test {

//Helper method to convert int arrays into Lists
static List<Integer> intArrayAsList(final int[] a) {
    if(a == null)
        throw new NullPointerException();
    return new AbstractList<Integer>() {

        @Override
        public Integer get(int i) {
            return a[i];//autoboxing
        }
        @Override
        public Integer set(int i, Integer val) {
            final int old = a[i];
            a[i] = val;//auto-unboxing
            return old;//autoboxing
        }
        @Override
        public int size() {
            return a.length;
        }
    };
}

public static void main(final String[] args) {
    int[] a = {1, 2, 3, 4, 5};
    Collections.reverse(intArrayAsList(a));
    System.out.println(Arrays.toString(a));
}
}

Attenzione agli svantaggi della boxe/unboxing

 1
Author: DennisTemper, 2011-06-09 10:03:56

Usando un lambda potresti farlo (compila in jdk lambda):

public static void main(String ars[]) {
        TransformService transformService = (inputs) -> {
            int[] ints = new int[inputs.size()];
            int i = 0;
            for (Integer element : inputs) {
                ints[ i++ ] = element;
            }
            return ints;
        };

        List<Integer> inputs = new ArrayList<Integer>(5) { {add(10); add(10);} };

        int[] results = transformService.transform(inputs);
    }

    public interface TransformService {
        int[] transform(List<Integer> inputs);
    }
 0
Author: NimChimpsky, 2016-11-24 16:13:39