Comment puis-je créer un flux à partir d'un tableau?


133

Actuellement, chaque fois que j'ai besoin de créer un flux à partir d'un tableau, je le fais

String[] array = {"x1", "x2"};
Arrays.asList(array).stream();

Existe-t-il un moyen direct de créer un flux à partir d'un tableau?

Réponses:


201

Vous pouvez utiliser Arrays.stream Eg

Arrays.stream(array);

Vous pouvez également utiliser Stream.ofcomme mentionné par @fge, qui ressemble à

public static<T> Stream<T> of(T... values) {
    return Arrays.stream(values);
}

Mais note Stream.of(intArray)retournera Stream<int[]>alors que Arrays.stream(intArr)retournera à IntStreamcondition que vous passiez un tableau de type int[]. Donc, en un mot pour le type primitif, vous pouvez observer la différence entre 2 méthodes Eg

int[] arr = {1, 2};
Stream<int[]> arr1 = Stream.of(arr);

IntStream stream2 = Arrays.stream(arr); 

Lorsque vous passez un tableau primitif à Arrays.stream, le code suivant est appelé

public static IntStream stream(int[] array) {
    return stream(array, 0, array.length);
}

et lorsque vous passez un tableau primitif au Stream.ofcode suivant, il est appelé

 public static<T> Stream<T> of(T t) {
     return StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false);
 }

Par conséquent, vous obtenez des résultats différents.

Mise à jour : comme mentionné par le commentaire de Stuart Marks La surcharge de sous-plage de Arrays.streamest préférable à l'utilisation Stream.of(array).skip(n).limit(m)car la première donne un flux SIZED alors que la seconde ne le fait pas. La raison est que limit(m)ne sait pas si la taille est m ou inférieur à m, alors Arrays.streamne vérifie gamme et connaît la taille exacte du flux Vous pouvez lire le code source pour la mise en œuvre de flux retourné par Arrays.stream(array,start,end) ici , alors que pour la mise en œuvre flux retourné par Stream.of(array).skip().limit()est - dans cette méthode .


9
Cette réponse est meilleure car Arrays.streama tous les cas surchargés pour les tableaux primitifs. C'est à direStream.of(new int[]{1,2,3}) vous donnera un Stream<int[]>considérant vous Arrays.streamrendra un IntStreamqui est probablement ce que vous voulez. Donc +1
user2336315

3
@Dima Je suppose que c'est une question de goût. Je veux dire, mieux dans un sens Stream.ofpourrait vous donner des surprises (comme lorsque vous appelezArrays.asList avec un tableau primitif et que les gens attendent un List<Integer>retour) :-)
user2336315

3
Arrays.streamprend en charge la diffusion en continu d'une plage du tableau, ce qui IntStream.ofne le fait pas. En revanche, Stream.ofc'est le meilleur choix si vous voulez une Stream<int[]>taille 1
Holger

4
@Dima La surcharge de sous-plage de Arrays.streamest préférable à l'utilisation Stream.of(array).skip(n).limit(m)car la première donne un flux SIZED alors que la seconde ne le fait pas. La raison est que limit(m)cela ne sait pas si la taille est mou inférieure à m, alors Arrays.streamque la plage vérifie et connaît la taille exacte du flux.
Stuart marque le

6
Pour les lecteurs intéressés à voir ce petit drame conclu, Arrays.stream(array,start,end)renvoie a Streamdont l'implémentation est ici , alors que Stream.of(array).skip().limit()retourne a Streamdont l'implémentation est dans cette méthode .
Stuart marque le

43

Alternative à la solution de @ sol4me:

Stream.of(theArray)

De la différence entre ceci et Arrays.stream(): cela fait une différence si votre tableau est de type primitif. Par exemple, si vous faites:

Arrays.stream(someArray)

someArrayest a long[], il retournera a LongStream. Stream.of(), d'autre part, retournera un Stream<long[]>avec un seul élément.


1
@Dima bien sûr, mais Arrays.stream()fonctionne aussi pour cela
fge

2
Eh bien, en ce qui concerne les flux, la commodité! Pas besoin d'appeler *Stream.of()lorsque vous avez Arrays.stream()affaire à des tableaux primitifs. Et pour ce qui est des tableaux qui ne sont pas des objets réels, eh bien, c'est Java, c'est le cas depuis la version 1.0, alors traitez-le; ruminer sur cela n'aide à rien
fge

2
@Dima et le vôtre aussi; vous considérez que ce Arrays.stream()n'est pas pratique, je considère que c'est pratique. Assez dit.
fge

2
@Dima oui, je trouve que votre argument *Stream.of()est plus commode pour être fallacieux; parce que c'est une question de préférences . Je préfère Arrays.stream()pour de tels cas, ce qui le rend faux en règle générale qui Stream.of()est plus pratique (algèbre Peano).
fge

3
@Dima: c'est une question de préférence. Les différences sont si incroyablement minuscules que cela n'a aucune importance. Plus précisément: une différence de quelques caractères n'est rien . Une importation supplémentaire dans un package à l'intérieur des bibliothèques standard n'est rien . Et vraiment, créer manuellement un tableau au lieu d'une surcharge varargs n'est rien .
Jeroen Vannevel

14
Stream.of("foo", "bar", "baz")

Ou, si vous possédez déjà un tableau, vous pouvez également faire

Stream.of(array) 

Pour les types primitifs, utilisez IntStream.ofou LongStream.ofetc.


Ce que je ne comprends pas, c'est que lorsqu'un int[]peut être passé à une méthode acceptant des varargs, pourquoi ne pas Stream.of(intArray)produire un à la Stream<Integer>place de Stream<int[]>? En outre, y a-t-il un raisonnement technique pour lequel il existe des classes Stream spécialisées pour les primitives?
asgs

1
Les primitives Java sont des bêtes étranges. int[]n'est pas comme les autres tableaux. Ce n'est pas une sous - classe Object[], mais il est une sous - classe Object. Ainsi, lorsque vous le transmettez à Stream.of, il est considéré comme le Objectparamètre, et vous obtenez un flux de int[]. C'est l'une des raisons d'avoir des classes spécialisées pour les primitifs - si vous ne créez pas de flux à partir de tableaux primitifs, ce serait assez pénible. L'autre raison est que les classes spécialisées sont plus efficaces, car elles n'ont pas besoin de supporter les Objectfrais généraux de la boxe (conversion inten Integerpour faire ressembler à des objets normaux).
Dima

Ah, puisque int[]c'est un Object, il correspondrait à la méthode surchargée of(T t)et donc il retourne Stream<int[]>. Donc, théoriquement, si cette méthode n’était pas disponible, nous aurions eu le Stream<Integer>retour? ou peut-être que cela entraîne une erreur de compilation car il n'a pas pu trouver la méthode correspondante? ie int[]ne peut pas être traité commeT...
asgs

1
Non, nous n'obtiendrions toujours pas de Stream<Integer>cette façon, car Stream.of(t ... T) cela correspondrait toujours de la même manière.
Dima

0

Vous pouvez également le faire par une méthode de bas niveau qui a l'option parallèle:

Mise à jour: utilisez full array.length (pas length - 1).

/** 
 * Creates a new sequential or parallel {@code Stream} from a
 * {@code Spliterator}.
 *
 * <p>The spliterator is only traversed, split, or queried for estimated
 * size after the terminal operation of the stream pipeline commences.
 *
 * @param <T> the type of stream elements
 * @param spliterator a {@code Spliterator} describing the stream elements
 * @param parallel if {@code true} then the returned stream is a parallel
 *        stream; if {@code false} the returned stream is a sequential
 *        stream.
 * @return a new sequential or parallel {@code Stream}
 *
 * <T> Stream<T> stream(Spliterator<T> spliterator, boolean parallel)
 */

StreamSupport.stream(Arrays.spliterator(array, 0, array.length), true)

0

Vous pouvez utiliser Arrays.stream:

Arrays.stream (tableau); 

Cela garantit le type de retour de vapeur en fonction de votre type d'entrée de tableau si son String []retourne alors Stream<String>, si int []alors retourneIntStream

Lorsque vous connaissez déjà le tableau de type d'entrée, il est bon d'en utiliser un spécifique comme pour le type d'entrée int[]

 IntStream.of (tableau); 

Cela renvoie Intstream.

Dans le premier exemple, Java utilise la méthode overloadingpour rechercher une méthode spécifique en fonction des types d'entrée, tandis que dans le second, vous connaissez déjà le type d'entrée et l'appel d'une méthode spécifique.


0

rarement vu, mais c'est le moyen le plus direct

Stream.Builder<String> builder = Stream.builder();
for( int i = 0; i < array.length; i++ )
  builder.add( array[i] );
Stream<String> stream = builder.build();
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.