80 votes

Convertir un tableau d'objets en un tableau de leurs types primitifs

Si vous avez un tableau d'objets Java qui ont un type primitif (par exemple Byte, Integer, Char, etc). Existe-t-il un moyen simple de le convertir en un tableau du type primitif? En particulier, est-il possible de le faire sans avoir à créer un nouveau tableau et à boucler à travers le contenu.

Donc, par exemple, étant donné

Integer[] array

quel est le moyen le plus simple de le convertir en

int[] intArray

Malheureusement, c'est quelque chose que nous devons faire assez fréquemment lors de l'interface entre Hibernate et certaines bibliothèques tierces sur lesquelles nous n'avons aucun contrôle. Il semble que ce serait une opération assez courante, donc je serais surpris s'il n'y avait pas de raccourci.

Merci pour votre aide!

91voto

Guillaume Points 8549

Encore une fois, Apache Commons Lang est votre ami. Ils fournissent ArrayUtils.toPrimitive() qui fait exactement ce dont vous avez besoin. Vous pouvez spécifier comment vous voulez gérer les valeurs nulles.

75voto

Alex Points 1092

Avec streams introduits en Java 8, cela peut être fait :

int[] intArray = Arrays.stream(array).mapToInt(Integer::intValue).toArray();

Cependant, il n'y a actuellement que des streams primitifs pour int, long et double. Si vous avez besoin de convertir vers un autre type primitif tel que byte, la manière la plus courte sans bibliothèque externe est la suivante :

byte[] byteArray = new byte[array.length];
for(int i = 0; i < array.length; i++) byteArray[i] = array[i];

Ou la boucle for peut être remplacée par un stream si vous le souhaitez :

IntStream.range(0, array.length).forEach(i -> byteArray[i] = array[i]);

Tous ces exemples lèveront une NullPointerException si un de vos éléments est null.

2 votes

Au lieu de Integer::intValue, vous pouvez également utiliser i -> i (qui utilise le déboxage).

1 votes

@robinst Et le déballage est le compilateur qui appelle Integer::intValue pour vous, pourquoi créer une nouvelle lambda lorsque la méthode est déjà disponible ?

0 votes

@Andreas Simplement en mentionnant une autre option, le choix final dépendra du style de code/préférence personnelle. J'ai également effectué une micro-analyse comparative (en utilisant JMH) des deux approches, et elles présentent des performances équivalentes.

40voto

Zach Scrivena Points 15052

Malheureusement, il n'y a rien dans la plateforme Java qui le fait. En passant, vous devez également gérer explicitement les éléments null dans le tableau Integer[] (quel int allez-vous utiliser pour ceux-ci ?).

6 votes

Bon point concernant les nulls. Pour mes besoins, j'aurais accepté qu'une exception soit lancée si l'une des entrées est nulle, de la même manière qu'une NullPointerException est lancée lorsque vous déballez un objet.

2 votes

Cette réponse n'est plus valable avec Java 8, voir la réponse d'Alex.

27voto

Paul Bellora Points 26524

En utilisant Guava:

int[] intArray = Ints.toArray(Arrays.asList(array));

Documentation:

3voto

Aaron Digulla Points 143830

En particulier, cela peut-il être fait sans avoir à créer un nouveau tableau et à parcourir son contenu.

Vous ne pouvez pas convertir un tableau d'entiers en int (c'est-à-dire que vous ne pouvez pas changer le type des éléments d'un tableau) en Java. Vous devez donc soit créer un nouveau tableau int[] et copier les valeurs des objets Integer dedans, soit utiliser un adaptateur:

class IntAdapter {
    private Integer[] array;
    public IntAdapter (Integer[] array) { this.array = array; }
    public int get (int index) { return array[index].intValue(); }
}

Cela peut rendre votre code un peu plus lisible et l'objet IntAdapter ne consommera que quelques octets de mémoire. Le gros avantage d'un adaptateur est que vous pouvez gérer des cas spéciaux ici:

class IntAdapter {
    private Integer[] array;
    public int nullValue = 0;
    public IntAdapter (Integer[] array) { this.array = array; }
    public int get (int index) { 
        return array[index] == null ? nullValue : array[index].intValue();
    }
}

Une autre solution est d'utiliser Commons Primitives qui contient de nombreux adaptateurs prédéfinis. Dans votre cas, jetez un œil à ListIntList.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X