Question Comment convertir List en int [] en Java?


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

Je suis nouveau à Java. Comment puis-je convertir un List<Integer> à int[] en Java? Je suis confus parce que List.toArray() retourne effectivement un Object[], qui peut être moulé à 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 faire cela.


452
2018-06-06 20:20


origine


Réponses:


Malheureusement, je ne crois pas vraiment est 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 à int
  • Vous ne pouvez pas utiliser int comme argument de type pour les génériques, il serait donc avoir être un intméthode spécifique (ou une méthode qui utilise la réflexion pour faire de la supercherie).

Je crois qu'il existe des 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 j'ai peur :(

Même si le Arrays La classe est apparue avant l'arrivée des génériques en Java, il faudrait quand même inclure toutes les surcharges horribles si elles étaient introduites aujourd'hui (en supposant que vous vouliez utiliser des tableaux primitifs).


174
2018-06-06 20:28



Personne n'a encore mentionné les flux ajoutés dans Java 8 alors voici ce qu'il se passe:

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

Processus de pensée:

  • simple Stream#toArray résultats Object[], alors ce n'est pas ce que nous voulons. Aussi Stream#toArray(IntFunction<A[]> generator) ne fait pas ce que nous voulons parce que le type générique A ne peut pas représenter une primitive int
  • donc ce serait bien d'avoir un flux qui pourrait gérer le type primitif int, parce que c'est toArray méthode reviendra très probablement aussi int[] tableau (renvoyant quelque chose d'autre comme Object[] ou même en boîte Integer[] serait contre nature ici). Et heureusement, Java 8 a un tel flux: IntStream
  • alors maintenant seule chose que nous devons comprendre est de savoir comment convertir notre Stream<Integer> (qui sera retourné de list.stream()) à ce brillant IntStream. Ici mapToInt méthode vient à la rescousse. Tout ce que nous devons faire est de fournir une cartographie de Integer à int. Nous pourrions utiliser quelque chose comme Integer#getValue qui revient 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, car le compilateur sait que le résultat de ce lambda doit être int (lambda dans mapToInt est la mise en œuvre de ToIntFunction interface qui attend corps pour int applyAsInt(T value) méthode qui devrait revenir int).

    Nous pouvons donc simplement écrire

    mapToInt((Integer i)->i)

    ou plus simple (depuis Integer i type peut être déduit par le compilateur car List<Integer>#stream() résultats Stream<Integer>)

    mapToInt(i -> i) 


392
2018-05-30 00:05



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

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

Cela vous évite d'avoir à faire la conversion de tableau intermédiaire que l'équivalent de Commons Lang exige vous-même.


180
2017-07-04 21:32



La façon la plus simple de le faire est de faire usage de Apache Commons Lang. Il a une classe pratique ArrayUtils qui peut faire ce que vous voulez. Utilisez le toPrimitiveméthode avec la surcharge pour un tableau de Integers.

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 Integer de la bonne taille. Vous pouvez également utiliser un tableau Integer statique de longueur 0 et laisser Java allouer un tableau de la bonne taille:

static final Integer[] NO_INTS = new Integer[0];
   ....
int[] intArray2 = ArrayUtils.toPrimitive(myList.toArray(NO_INTS));

166
2018-06-06 20:48



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 l'indexation coûteuse de la liste (puisqu'une liste n'est pas nécessairement une liste de tableaux, mais peut être une liste chaînée, pour laquelle l'accès aléatoire est coûteux)


47
2018-06-08 14:55



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

Utiliser les collections stream() fonction et mappage à ints, vous obtiendrez un IntStream. Avec le IntStream nous pouvons appeler toArray () qui nous donne int []

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

à int []

à IntStream


30
2017-09-09 04:30



Voici Java 8 code de ligne unique pour cette

public int[] toIntArray(List<Integer> intList){
       return intList.stream().mapToInt(Integer::intValue).toArray();
}

12
2017-07-11 10:38



Je vais en jeter un de plus ici. J'ai remarqué plusieurs utilisations des boucles for, mais vous n'avez même besoin de rien dans la boucle. Je ne le mentionne que parce que la question initiale essayait de trouver un 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 permettait plusieurs déclarations dans une boucle for comme le fait C ++, nous pourrions aller plus loin et faire pour (int i = 0, Iterator it ...

À la fin cependant (cette partie est juste mon opinion), si vous allez avoir une fonction d'aide ou une méthode pour faire quelque chose pour vous, mettez-le en place et oubliez-le. Ce peut être une doublure ou dix; Si vous ne le regarderez plus jamais, vous ne saurez pas la différence.


6
2017-07-23 15:57



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
2017-10-31 08:04



Si vous ne faites que cartographier un Integer à un int alors vous devriez considérer en utilisant le parallélisme, puisque votre logique de mappage ne repose sur aucune variable en dehors de sa portée.

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

Juste être conscient de cela

Notez que le parallélisme n'est pas automatiquement plus rapide que l'exécution des opérations en série, bien que cela puisse être le cas si vous avez suffisamment de cœurs de données et de processeurs. Alors que les opérations agrégées vous permettent d'implémenter plus facilement le parallélisme, il est toujours de votre responsabilité de déterminer si votre application est adaptée au parallélisme.


Il existe deux manières de mapper des entiers à leur forme primitive:

  1. Par l'intermédiaire d'un ToIntFunction.

    mapToInt(Integer::intValue)
    
  2. Via explicite déballage avec l'expression de lambda.

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

    mapToInt(i -> i)
    

Étant donné une liste avec un null valeur

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

Voici trois options à gérer null:

  1. Filtrer le null valeurs avant la cartographie.

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

    int[] arr = list.parallelStream().map(i -> i == null ? -1 : i).mapToInt(Integer::intValue).toArray();
    
  3. Manipuler null à l'intérieur de l'expression lambda.

    int[] arr = list.parallelStream().mapToInt(i -> i == null ? -1 : i.intValue()).toArray();
    

5
2017-11-30 12:54



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
2018-02-27 19:18