J'ai un tableau de primitives, par exemple pour int, int [] foo. Cela peut être de petite taille ou non.
int foo[] = {1,2,3,4,5,6,7,8,9,0};
Quelle est la meilleure façon d'en créer un Iterable<Integer>
?
Iterable<Integer> fooBar = convert(foo);
Remarques:
Veuillez ne pas répondre en utilisant des boucles (à moins que vous ne puissiez donner une bonne explication sur la façon dont le compilateur fait quelque chose d'intelligent à leur sujet?)
Notez également que
int a[] = {1,2,3};
List<Integer> l = Arrays.asList(a);
Ne compilera même pas
Type mismatch: cannot convert from List<int[]> to List<Integer>
Vérifiez également Pourquoi un tableau n'est-il pas attribuable à Iterable? avant de répondre.
De plus, si vous utilisez une bibliothèque (par exemple, Guava), veuillez expliquer pourquoi c'est la meilleure. (Parce que son de Google n'est pas une réponse complète: P)
Enfin, comme il semble y avoir un travail à faire à ce sujet, évitez de publier du code de travail à domicile.
Réponses:
Bien que vous deviez utiliser un
Integer
tableau (pas unint
tableau) pour que cela fonctionne.Pour les primitives, vous pouvez utiliser la goyave:
Pour Java8: (d'après la réponse de Jin Kwon)
la source
int
, pasInteger
2)List
est déjàIterable
donc la troisième ligne est inutile.juste mes 2 cents:
la source
Iterator<Character>
partir d'un fichierString
. Implémenter le vôtreIterator
semble être le seul moyen d'éviter d'itérer inutilement toutes les valeurs à convertir du type d'objet au type primitif (via GuavaInts.asList()
par exemple), juste pour pouvoir obtenir unIterator
de celuiList
qui a été créé.Avec Java 8, vous pouvez le faire.
la source
Guava fournit l'adaptateur souhaité en tant que Int.asList () . Il existe un équivalent pour chaque type primitif dans la classe associée, par exemple
Booleans
pourboolean
, etc.Les suggestions ci - dessus à l' utilisation
Arrays.asList
ne fonctionnera pas, même si elles compilent parce que vous obtenez uneIterator<int[]>
plutôt queIterator<Integer>
. Ce qui se passe, c'est qu'au lieu de créer une liste sauvegardée par votre tableau, vous avez créé une liste à 1 élément de tableaux, contenant votre tableau.la source
J'ai eu le même problème et je l'ai résolu comme ceci:
L'itérateur lui-même est un paresseux
UnmodifiableIterator
mais c'est exactement ce dont j'avais besoin.la source
Dans Java 8 ou version ultérieure,
Iterable
une interface fonctionnelle est renvoyéeIterator
. Vous pouvez donc le faire.la source
Tout d'abord, je ne peux que convenir que
Arrays.asList(T...)
c'est clairement la meilleure solution pour les types Wrapper ou les tableaux avec des types de données non primitifs. Cette méthode appelle un constructeur d'uneAbstractList
implémentation statique privée simple dans laArrays
classe qui enregistre essentiellement la référence de tableau donnée en tant que champ et simule une liste en remplaçant les méthodes nécessaires.Si vous pouvez choisir entre un type primtive ou un type Wrapper pour votre tableau, j'utiliserais le type Wrapper pour de telles situations, mais bien sûr, ce n'est pas toujours utile ou obligatoire. Il n'y aurait que deux possibilités que vous pouvez faire:
1) Vous pouvez créer une classe avec une méthode statique pour chaque tableau de type de données primitif (
boolean, byte, short, int, long, char, float, double
renvoyant unIterable<
WrapperType>
. Ces méthodes utiliseraient des classes anonymes deIterator
(en plusIterable
) qui sont autorisés à contenir la référence de l'argument de la méthode comprenant (par exemple unint[]
) comme champ afin d'implémenter les méthodes.-> Cette approche est performante et vous permet d'économiser de la mémoire (sauf pour la mémoire des méthodes nouvellement créées, même si l'utilisation
Arrays.asList()
prendrait de la mémoire de la même manière)2) Puisque les tableaux n'ont pas de méthodes (comme à lire sur le côté vous avez lié), ils ne peuvent pas non plus fournir d'
Iterator
instance. Si vous êtes vraiment trop paresseux pour écrire de nouvelles classes, vous devez utiliser une instance d'une classe déjà existante qui implémenteIterable
car il n'y a pas d'autre moyen que l'instanciationIterable
ou un sous-type.La SEULE façon de créer une implémentation de dérivé de collection existante
Iterable
consiste à utiliser une boucle (sauf que vous utilisez des classes anonymes comme décrit ci-dessus) ou que vous instanciez uneIterable
classe d'implémentation dont le constructeur autorise un tableau de type primitif (carObject[]
n'autorise pas les tableaux avec des éléments de type primitif) mais pour autant que je sache, l'API Java ne présente pas une classe comme celle-là.La raison de la boucle peut être expliquée facilement:
pour chaque collection, vous avez besoin d'objets et les types de données primitifs ne sont pas des objets. Les objets sont beaucoup plus gros que les types primitifs de sorte qu'ils nécessitent des données supplémentaires qui doivent être générées pour chaque élément du tableau de types primitifs. Cela signifie que si deux méthodes sur trois (utiliser
Arrays.asList(T...)
ou utiliser une collection existante) nécessitent un agrégat d'objets, vous devez créer pour chaque valeur primitive de votreint[]
tableau l'objet wrapper. La troisième façon utiliserait le tableau tel quel et l'utiliserait dans une classe anonyme car je pense que c'est préférable en raison des performances rapides.Il existe également une troisième stratégie utilisant un
Object
argument en tant qu'argument pour la méthode où vous souhaitez utiliser le tableau ouIterable
et il faudrait des vérifications de type pour déterminer le type de l'argument, mais je ne le recommanderais pas du tout, car vous devez généralement le faire. considérez que l'objet n'a pas toujours le type requis et que vous avez besoin d'un code séparé dans certains cas.En conclusion, c'est la faute du système problématique Generic Type de Java qui ne permet pas d'utiliser des types primitifs comme type générique ce qui permettrait d'économiser beaucoup de code en utilisant simplement
Arrays.asList(T...)
. Vous devez donc programmer pour chaque tableau de type primitif, vous avez besoin d'une telle méthode (qui ne fait fondamentalement aucune différence pour la mémoire utilisée par un programme C ++ qui créerait pour chaque argument de type utilisé une méthode distincte.la source
Vous pouvez utiliser à
IterableOf
partir de Cactoos :Ensuite, vous pouvez le transformer en liste en utilisant
ListOf
:Ou simplement ceci:
la source
Bien qu'une réponse similaire ait déjà été publiée, je pense que la raison d'utiliser le nouveau PrimitiveIterator.OfInt n'était pas claire. Une bonne solution consiste à utiliser Java 8 PrimitiveIterator car il est spécialisé pour les types int primitifs (et évite la pénalité supplémentaire de boxing / unboxing):
Réf: https://doc.bccnsoft.com/docs/jdk8u12-docs/api/java/util/PrimitiveIterator.OfInt.html
la source
Dans java8, le flux IntSteam peut être encadré en flux d'entiers.
Je pense que les performances sont importantes en fonction de la taille du tableau.
la source