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é?
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é?
Réponses:
Comme l'a dit Eran, ce n'est pas le seul qui manque.
Un BooleanStream
serait inutile, un ByteStream
(s'il existait) peut être traité comme un InputStream
ou converti en IntStream
(comme peut short
), et float
peut être traité comme un DoubleStream
.
Comme il char
n'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 BooleanStream
serait 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?
BooleanStream
serait inutile": pourquoi?
reduce(Boolean::logicalAnd)
ou reduce(Boolean::logicalOr)
sur un boolean[]
? Après tout, les méthodes logicalAnd
et logicalOr
ont é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.
Boolean::logicalAnd
existe, 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.
while (i < limit)
, mais en aucun cas personne ne doit le faire [en utilisant les instructions de montage de branchement et de saut]"
<Primitive>Stream
pour chaque type primitif est parce que cela va trop gonfler l'API. La bonne question à poser est "pourquoi y a-t-il IntStream
du 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>
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 CharStream
il 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.
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).
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
100K+ of JDK footprint
?
Ce ne sont pas seulement les char
tableaux qui ne sont pas pris en charge.
Il n'y a que 3 types de flux primitifs - IntStream
, LongStream
et DoubleStream
.
Par conséquent, Arrays
a 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.
char
est 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 char
avait 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.Normalizer
pour une forme canonique unique de points de code / chaînes Unicode.