Pourquoi char [] est-il le seul tableau non pris en charge par Arrays.stream ()?

43

En parcourant les façons de convertir des tableaux primitifs en flux, j'ai constaté qu'ils char[]ne sont pas pris en charge alors que d'autres types de tableaux primitifs sont pris en charge. Une raison particulière de les laisser de côté?

cavalier fantôme
la source
3
stackoverflow.com/questions/22435833/… Ce fil OMI répond à une question connexe
Mark Bramnik

Réponses:

31

Comme l'a dit Eran, ce n'est pas le seul qui manque.

Un BooleanStreamserait inutile, un ByteStream(s'il existait) peut être traité comme un InputStreamou converti en IntStream(comme peut short), et floatpeut être traité comme un DoubleStream.

Comme il charn'est pas en mesure de représenter tous les personnages de toute façon (voir lié), ce serait un peu un flux hérité. Bien que la plupart des gens n'aient pas à gérer les points de code de toute façon, cela peut sembler étrange. Je veux dire que vous utilisez String.charAt()sans penser "cela ne fonctionne pas dans tous les cas".

Certaines choses ont donc été laissées de côté parce qu'elles n'étaient pas jugées si importantes. Comme l'a dit JB Nizet dans la question liée :

Les concepteurs ont explicitement choisi d'éviter l'explosion des classes et des méthodes en limitant les flux primitifs à 3 types, car les autres types (char, short, float) peuvent être représentés par leur équivalent plus grand (int, double) sans pénalité de performance significative.

La raison BooleanStreamserait inutile, car vous n'avez que 2 valeurs et cela limite beaucoup les opérations. Il n'y a aucune opération mathématique à faire, et à quelle fréquence travaillez-vous avec beaucoup de valeurs booléennes de toute façon?

Kayaman
la source
7
"A BooleanStreamserait inutile": pourquoi?
glglgl
12
Est-il vraiment déraisonnable de supposer que quelqu'un pourrait avoir besoin de le faire, par exemple, reduce(Boolean::logicalAnd)ou reduce(Boolean::logicalOr)sur un boolean[]? Après tout, les méthodes logicalAndet logicalOront été ajoutées dans Java 8, donc je peux faire ces opérations de réduction d'un Stream<Boolean>… Au fait, vous pouvez diffuser sur un char[]aussi simple que CharBuffer.wrap(array).chars()ou CharBuffer.wrap(array).codePoints(), selon la sémantique que vous préférez.
Holger
2
@Holger simplement parce qu'il Boolean::logicalAndexiste, il ne garantit pas nécessairement l'existence d'un BooleanStream. Ceux-ci peuvent être utilisés dans des situations lambda non stream après tout. Je peux imaginer que quelqu'un voudra faire reduce(Boolean::logicalAnd), mais en aucun cas ce que quelqu'un besoin de le faire.
Kayaman
4
Je ne vois pas quel argument vous essayez de faire. Dans sa forme extrême: "Je peux imaginer que quelqu'un voudrait le faire while (i < limit), mais en aucun cas personne ne doit le faire [en utilisant les instructions de montage de branchement et de saut]"
Alexander - Reinstate Monica
11
Il me semble que la seule raison pour laquelle il n'y en a pas <Primitive>Streampour chaque type primitif est parce que cela va trop gonfler l'API. La bonne question à poser est "pourquoi y a-t-il IntStreamdu tout?" et la réponse malheureuse est que le système de type de Java n'est pas suffisamment étoffé pour s'exprimer Stream<int>sans toutes les dépenses de performance liées à l'utilisation Integer. Si Java avait des types de valeur, qui pourraient être alloués sur la pile ou incorporés directement en ligne dans d'autres structures de données, il n'y aurait rien de plus nécessaireStream<T>
Alexander - Reinstate Monica
32

Bien sûr, la réponse est " parce que c'est ce que les concepteurs ont décidé ". Il n'y a aucune raison technique pour laquelle CharStreamil ne pourrait pas exister.

Si vous souhaitez une justification, vous devez généralement désactiver la liste de diffusion OpenJDK *. La documentation du JDK n'a pas l'habitude de justifier pourquoi quelque chose est pourquoi c'est.

Quelqu'un a demandé

L'utilisation d'IntStream pour représenter le flux de caractères / octets est un peu gênant. Faut-il également ajouter CharStream et ByteStream?

La réponse de Brian Goetz (Java Language Architect) dit

Réponse courte: non.

Cela ne vaut pas 100K + d'empreinte JDK chacun pour ces formulaires qui ne sont presque jamais utilisés. Et si nous les ajoutions, quelqu'un demanderait court, flottant ou booléen.

Autrement dit, si les gens insistaient pour que nous ayons toutes les spécialisations primitives, nous n'aurions pas de spécialisations primitives. Ce qui serait pire que le statu quo.

La source

Il dit aussi la même chose ailleurs

Si vous souhaitez les traiter comme des caractères, vous pouvez les convertir assez facilement en caractères. Cela ne semble pas être un cas d'utilisation suffisamment important pour avoir un ensemble complet de flux. (Idem pour Short, Byte, Float).

La source

TL; DR: Ne vaut pas le coût de maintenance.


* Si vous êtes curieux, la requête Google que j'ai utilisée était

site:http://mail.openjdk.java.net/ charstream
Michael
la source
2
Quelqu'un pourrait-il clarifier ce qu'ils entendent 100K+ of JDK footprint?
yassin
3
@yassin Quelqu'un doit écrire le code. Il estime que chaque spécialisation de flux représente plus de 100 000 lignes de code
Michael
3
@BulgarSadykov De telles questions sur " pourquoi X est comme Y " sont souvent fermées car basées sur des opinions car il est impossible de lire dans l'esprit de l'auteur original et, à moins qu'elles ne se présentent, vous n'obtiendrez que des conjectures. Si je demande "comment envoyer une demande POST avec le client HTTP d'Apache?", Toute personne familiarisée avec la bibliothèque peut y répondre. Pourquoi une bibliothèque est conçue de la façon dont il est généralement impossible de répondre. La seule raison pour laquelle nous sommes en mesure de répondre à cette vraiment est parce qu'il ya un dossier public de leurs conversations. C'est ce que j'essayais de faire avec la première phrase.
Michael
2
@BulgarSadykov, cela rappelle également cela, mentionne le blog d'Eric Lippert, à propos de C #, mais sur le thème "Pourquoi la fonction Foo n'est pas implémentée dans le langage" stackoverflow.com/a/5588850/479251
Pac0
2
@BulgarSadykov En désaccord avec respect. Encore une fois, je répète mon exemple de question " comment envoyer une demande POST avec le client HTTP d'Apache? ". Une réponse à cette question ne commence clairement pas par " car c'est ce que les concepteurs ont décidé ". Je ne change pas le libellé, désolé.
Michael
7

Ce ne sont pas seulement les chartableaux qui ne sont pas pris en charge.

Il n'y a que 3 types de flux primitifs - IntStream, LongStreamet DoubleStream.

Par conséquent, Arraysa des méthodes qui convertissent int[], long[]et double[]aux courants primitifs correspondants.

Il n'y a pas de méthodes correspondantes pour boolean[], byte[], short[], char[]et float[], étant donné que ces types primitifs ont pas correspondant courants primitifs.

Eran
la source
4
"Puisque ces types primitifs n'ont pas de flux primitifs correspondants." Ensuite, la question de suivi serait "pourquoi"?
Federico klez Culloca
7
@FedericoklezCulloca répond à cette question de suivi ici
Eran
6

charest une partie dépendante du String- stockage des valeurs UTF-16. Un symbole Unicode, un point de code , est parfois une paire de caractères de substitution. Donc, toute solution simple avec des caractères ne couvre qu'une partie du domaine Unicode.

Il fut un temps qui charavait son propre droit d'être un type public. Mais de nos jours, il vaut mieux utiliser des points de code , un IntStream. Un flux d'ombles ne pouvait pas gérer directement les paires de substitution.

L'autre raison plus prosaïque est que le modèle de "processeur" JVM utilise un int"registre" aussi petit, gardant les booléens, les octets, les shorts et les caractères dans un tel emplacement de stockage de taille int. Pour ne pas nécessairement gonfler les classes java, on s'est abstenu de toutes les variantes de copie possibles.

Dans un avenir lointain, on pourrait s'attendre à ce que les types primitifs puissent fonctionner comme des paramètres de type génériques, fournissant a List<int>. Ensuite, nous pourrions voir un Stream<char>.

Pour le moment, mieux vaut éviter char, et peut-être utiliser java.text.Normalizerpour une forme canonique unique de points de code / chaînes Unicode.

Joop Eggen
la source