Comment convertir la liste en int [] en Java?


Ceci est similaire à cette question: Comment convertir int [] en Entier [] en Java?

Je suis nouveau sur Java. Comment puis-je convertir un List<Integer> à int[] en Java? Je suis confus parce que List.toArray() renvoie en fait un Object[], qui peut être converti en nether Integer[] ou int[].

En ce moment, j'utilise une boucle pour le faire:

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

Je suis sûr qu'il y a une meilleure façon de le faire.

Author: Community, 2009-06-07

17 answers

Malheureusement, je ne crois pas qu'il y ait vraiment une meilleure façon de le faire en raison de la nature de la gestion par Java des types primitifs, de la boxe, des tableaux et des génériques. En particulier:

  • List<T>.toArray ne fonctionnera pas car il n'y a pas de conversion de Integer en int
  • Vous ne pouvez pas utiliser intcomme argument de type pour les génériques, donc aurait pour être une méthode spécifique à int (ou une méthode qui utilisait la réflexion pour faire une supercherie méchante).

Je crois qu'il y a bibliothèques qui ont des versions générées automatiquement de ce type de méthode pour tous les types primitifs (c'est-à-dire qu'il y a un modèle qui est copié pour chaque type). C'est moche, mais c'est comme ça que je crains : (

Même si le Arrays la classe est sortie avant l'arrivée des génériques en Java, elle devrait toujours inclure toutes les surcharges horribles si elle était introduite aujourd'hui (en supposant que vous souhaitiez utiliser des tableaux primitifs).

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

Personne n'a encore mentionné les flux ajoutés dans Java 8, alors voilà:

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

Processus de Pensée:

  • simple Stream#toArray renvoie Object[], donc ce n'est pas ce que nous voulons. De plus, Stream#toArray(IntFunction<A[]> generator) ne fait pas ce que nous voulons car le type générique A ne peut pas représenter le primitif int
  • ce serait donc bien d'avoir un flux qui pourrait gérer le type primitif int, car sa méthode toArray retournera probablement aussi int[] array (renvoyant autre chose comme Object[] ou même boxed Integer[] ne serait pas naturel ici). Et heureusement Java 8 a un tel flux: IntStream
  • Alors maintenant, la seule chose que nous devons comprendre est de savoir comment convertir notre Stream<Integer> (qui sera renvoyé de list.stream()) en ce IntStream brillant. Ici mapToInt la méthode vient à la rescousse. Tout ce que nous devons faire est de fournir un mappage de Integer à int. Nous pourrions utiliser quelque chose comme Integer#getValue qui retourne int:

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

    (ou si quelqu'un préfère mapToInt(Integer::intValue) )

    Mais un code similaire peut être généré en utilisant unboxing, puisque le compilateur sait que le résultat de ce lambda doit être int (lambda dans mapToInt est l'implémentation de l'interface ToIntFunction qui attend le corps de la méthode int applyAsInt(T value) qui devrait renvoyer int).

    Donc nous pouvons simplement écrire

    mapToInt((Integer i)->i)

    Ou plus simple (puisque le type Integer i peut être déduit par le compilateur car List<Integer>#stream() renvoie Stream<Integer>)

    mapToInt(i -> i)

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

En plus de Communes Lang, vous pouvez le faire avec Goyave's méthode Ints.toArray(Collection<Integer> collection):

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

Cela vous évite d'avoir à effectuer vous-même la conversion de tableau intermédiaire requise par l'équivalent Commons Lang.

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

La façon la plus simple de le faire est d'utiliser Apache Commons Lang. Il a une classe ArrayUtils pratique qui peut faire ce que vous voulez. Utilisez le toPrimitive méthode avec la surcharge pour un tableau de Integer s.

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

De cette façon, vous ne réinventez pas la roue. Commons Lang a beaucoup de choses utiles que Java a laissées de côté. Ci-dessus, j'ai choisi de créer une liste entière de la bonne taille. Vous pouvez également utiliser un tableau entier statique de longueur 0 et laisser Java allouer un tableau de droite taille:

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

Légère modification de votre code pour éviter une indexation de liste coûteuse (car une liste n'est pas nécessairement une ArrayList, mais pourrait être une liste chaînée, pour laquelle l'accès aléatoire est coûteux)

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

Java 8 nous a donné un moyen facile de le faire via des flux...

En utilisant la fonction collections stream(), puis en mappant à ints, vous obtiendrez un IntStream. Avec le IntStream nous pouvons appeler toArray() ce qui nous donne int []

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

À int []

Pour IntStream

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

Voici Java 8 code simple ligne pour ce

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

Je vais en jeter un de plus ici. J'ai remarqué plusieurs utilisations de for loops, mais vous n'avez même pas besoin de quoi que ce soit à l'intérieur de la boucle. Je le mentionne uniquement parce que la question d'origine essayait de trouver du code moins verbeux.

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

Si Java autorisait plusieurs déclarations dans une boucle for comme le fait C++, nous pourrions aller plus loin et faire for(int i = 0, Itérateur...

À la fin cependant (cette partie est juste mon opinion), si vous allez avoir une fonction ou une méthode d'aide pour faire quelque chose pour vous, il suffit de le mettre en place et l'oublier. Cela peut être un one-liner ou dix; si vous ne le regardez plus jamais, vous ne saurez pas la différence.

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

Cette boucle simple est toujours correcte! pas de bugs

  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

Si vous mappez simplement un Integer à un intalors vous devriez considérer en utilisant le parallélisme, car votre logique de mappage ne repose sur aucune variable en dehors de sa portée.

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

Soyez juste conscient de cela

Notez que le parallélisme n'est pas automatiquement plus rapide que d'effectuer des opérations en série, bien que cela puisse l'être si vous avez suffisamment de données et de cœurs de processeur. Bien que les opérations d'agrégation vous permettent d'implémenter plus facilement le parallélisme, il reste votre responsabilité de déterminer si votre application convient au parallélisme.


Il existe deux façons de mapper les entiers à leur forme primitive:

  1. Via un ToIntFunction.

    mapToInt(Integer::intValue)
    
  2. Via explicite unboxing avec une expression lambda.

    mapToInt(i -> i.intValue())
    
  3. Via un déballage implicite (auto-) avec une expression lambda.

    mapToInt(i -> i)
    

Étant donné une liste avec une valeur null

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

Voici trois options pour gérer null:

  1. Filtrez les valeurs null avant le mappage.

    int[] arr = list.parallelStream().filter(Objects::nonNull).mapToInt(Integer::intValue).toArray();
    
  2. Mapper les valeurs null à une valeur par défaut.

    int[] arr = list.parallelStream().map(i -> i == null ? -1 : i).mapToInt(Integer::intValue).toArray();
    
  3. Poignée null à l'intérieur de l'expression 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

Il n'y a vraiment aucun moyen de" one-lining " ce que vous essayez de faire car toArray renvoie un Objet [] et vous ne pouvez pas convertir Object [] en int [] ou Integer [] en int []

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

Essayez aussi de Dollar (cochez cette révision):

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

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

Avec Eclipse Collections, vous pouvez faire ce qui suit si vous avez une liste de type 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);

Si vous avez déjà un type de collections Eclipse comme MutableList, vous pouvez faire ce qui suit:

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

Remarque: Je suis un committer pour les collections Eclipse

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

En commençant par java 8 cela peut être facilement réalisé en utilisant Stream API

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

Si vous souhaitez avoir plus d'informations sur la façon dont ce processus est terminé, id tiens à vous rediriger vers ce lien http://www.techiedelight.com/convert-stream-array-java/#2

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

Je vous recommande d'utiliserList<?> l'implémentation squelettique de l'API java collections, cela semble être très utile dans ce cas particulier:

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

Méfiez-vous des inconvénients de la boxe/unboxing

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

En utilisant un lambda, vous pouvez le faire (compile dans 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