Comment convertir un flux Java 8 en tableau?


776

Quelle est la manière la plus simple / la plus courte de convertir un Java 8 Streamen tableau?


2
Je vous suggère de revenir en arrière car la question était plus complète et montrait que vous aviez essayé quelque chose.
skiwi

2
@skiwi Merci! mais je pensais que le code tenté n'ajoutait pas vraiment plus d'informations à la question, et personne n'a encore crié "montrez-nous votre tentative" =)

17
@skiwi: Bien que je crie habituellement aux questions de faire mes devoirs à la place de moi, cette question particulière semble être plus claire sans aucun gâchis supplémentaire. Gardons-le bien rangé.
Honza Zidek

Vous pouvez trouver de nombreuses réponses et conseils dans les documents officiels du package: docs.oracle.com/javase/8/docs/api/java/util/stream/…
Christophe Roussy

Réponses:


1169

La méthode la plus simple consiste à utiliser la toArray(IntFunction<A[]> generator)méthode avec une référence de constructeur de tableau. Ceci est suggéré dans la documentation API de la méthode .

String[] stringArray = stringStream.toArray(String[]::new);

Ce qu'il fait, c'est trouver une méthode qui prend un entier (la taille) comme argument, et retourne a String[], qui est exactement ce que fait (l'une des surcharges de) new String[].

Vous pouvez également écrire le vôtre IntFunction:

Stream<String> stringStream = ...;
String[] stringArray = stringStream.toArray(size -> new String[size]);

Le but de IntFunction<A[]> generatorest de convertir un entier, la taille du tableau, en un nouveau tableau.

Exemple de code:

Stream<String> stringStream = Stream.of("a", "b", "c");
String[] stringArray = stringStream.toArray(size -> new String[size]);
Arrays.stream(stringArray).forEach(System.out::println);

Tirages:

a
b
c

8
et voici une explication pourquoi et comment la référence de constructeur de tableau fonctionne réellement: stackoverflow.com/questions/29447561/…
jarek.jpa

"Zenexer a raison, la solution devrait être: stream.toArray (String [] :: new);" ... Bon d'accord, mais il faut comprendre que la référence de la méthode est logiquement et fonctionnellement équivalente à toArray(sz -> new String[sz])donc je ne suis pas sûr que l'on puisse vraiment dire quelle doit ou doit être la solution.
scottb

3
@scottb sz -> new String[sz]crée une nouvelle fonction alors que la référence constructeur ne le fait pas. Cela dépend de combien vous appréciez le taux de récupération des ordures, je suppose.
WORMSS

3
@WORMSS Ce n'est pas le cas. Il (statiquement!) Crée une nouvelle private méthode , qui ne peut pas provoquer de désabonnement, et les deux versions doivent créer un nouvel objet. Une référence crée un objet qui pointe directement vers la méthode cible; un lambda crée un objet qui pointe vers celui généré private. Une référence à un constructeur devrait toujours être plus performante faute d'indirection et d'optimisation plus facile des VM, mais le barattage n'a rien à voir avec cela.
HTNW

2
@HTNW vous avez raison, mes excuses. C'était en fait ma tentative de débogage qui causait le désabonnement qui provoquait le désabonnement la première fois que j'ai essayé de le faire, donc je l'ai coincé dans ma tête que c'était comme ça. (Je déteste quand ça arrive).
WORMSS

41

Si vous souhaitez obtenir un tableau d'entiers, avec des valeurs de 1 à 10, à partir d'un flux, IntStream est à votre disposition.

Ici, nous créons un Stream avec une méthode Stream.of et convertissons un Stream en IntStream en utilisant un mapToInt. Ensuite, nous pouvons appeler la méthode toArray d'IntStream.

Stream<Integer> stream = Stream.of(1,2,3,4,5,6,7,8,9,10);
//or use this to create our stream 
//Stream<Integer> stream = IntStream.rangeClosed(1, 10).boxed();
int[] array =  stream.mapToInt(x -> x).toArray();

Voici la même chose, sans le Stream, en utilisant uniquement l'IntStream

int[]array2 =  IntStream.rangeClosed(1, 10).toArray();

16

Vous pouvez convertir un flux java 8 en un tableau à l'aide de ce simple bloc de code:

 String[] myNewArray3 = myNewStream.toArray(String[]::new);

Mais expliquons les choses davantage, tout d'abord, créons une liste de chaînes remplies de trois valeurs:

String[] stringList = {"Bachiri","Taoufiq","Abderrahman"};

Créez un flux à partir du tableau donné:

Stream<String> stringStream = Arrays.stream(stringList);

nous pouvons maintenant effectuer certaines opérations sur ce flux Ex:

Stream<String> myNewStream = stringStream.map(s -> s.toUpperCase());

et enfin le convertir en un tableau java 8 en utilisant ces méthodes:

Méthode 1-Classic (interface fonctionnelle)

IntFunction<String[]> intFunction = new IntFunction<String[]>() {
    @Override
    public String[] apply(int value) {
        return new String[value];
    }
};


String[] myNewArray = myNewStream.toArray(intFunction);

2 -Lambda expression

 String[] myNewArray2 = myNewStream.toArray(value -> new String[value]);

3- Référence de méthode

String[] myNewArray3 = myNewStream.toArray(String[]::new);

Référence de la méthode Explication:

C'est une autre façon d'écrire une expression lambda qui est strictement équivalente à l'autre.


7

Convertissez le texte en tableau de chaînes où séparez chaque valeur par une virgule et coupez chaque champ, par exemple:

String[] stringArray = Arrays.stream(line.split(",")).map(String::trim).toArray(String[]::new);

5

Vous pouvez créer un collecteur personnalisé qui convertit un flux en tableau.

public static <T> Collector<T, ?, T[]> toArray( IntFunction<T[]> converter )
{
    return Collectors.collectingAndThen( 
                  Collectors.toList(), 
                  list ->list.toArray( converter.apply( list.size() ) ) );
}

et une utilisation rapide

List<String> input = Arrays.asList( ..... );

String[] result = input.stream().
         .collect( CustomCollectors.**toArray**( String[]::new ) );

5
Pourquoi utiliseriez-vous ceci au lieu de Stream.toArray (IntFunction) ?
Didier L

J'avais besoin d'un collecteur pour passer à l'argument 2 Collectors.groupingByafin de pouvoir mapper un attribut à des tableaux d'objets par valeur d'attribut. Cette réponse me donne exactement cela. Aussi @DidierL.
Ole VV

3

L'utilisation de la toArray(IntFunction<A[]> generator)méthode est en effet un moyen très élégant et sûr de convertir (ou plus correctement, de collecter) un Stream en un tableau du même type de Stream.

Cependant, si le type du tableau retourné n'est pas important, la simple utilisation de la toArray()méthode est à la fois plus simple et plus courte. Par exemple:

    Stream<Object> args = Stream.of(BigDecimal.ONE, "Two", 3);
    System.out.printf("%s, %s, %s!", args.toArray());

0
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);

int[] arr=   stream.mapToInt(x->x.intValue()).toArray();

0
import java.util.List;
import java.util.stream.Stream;

class Main {

    public static void main(String[] args) {
        // Create a stream of strings from list of strings
        Stream<String> myStreamOfStrings = List.of("lala", "foo", "bar").stream();

        // Convert stream to array by using toArray method
        String[] myArrayOfStrings = myStreamOfStrings.toArray(String[]::new);

        // Print results
        for (String string : myArrayOfStrings) {
            System.out.println(string);
        }
    }
}

Essayez-le en ligne: https://repl.it/@SmaMa/Stream-to-array


Quelle est la différence entre votre réponse et la réponse acceptée?
Long Nguyen

@LongNguyen C'est un exemple complet comprenant un scénario de relecture en ligne, pas seulement un extrait.
Sma Ma

-1
     Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);

     Integer[] integers = stream.toArray(it->new Integer[it]);

-2

Vous pouvez le faire de plusieurs façons. Toutes les méthodes sont techniquement les mêmes, mais l'utilisation de Lambda simplifierait une partie du code. Disons que nous initialisons d'abord une liste avec String, appelons-la personnes.

List<String> persons = new ArrayList<String>(){{add("a"); add("b"); add("c");}};
Stream<String> stream = persons.stream();

Vous pouvez maintenant utiliser l'une des méthodes suivantes.

  1. Utilisation de Lambda Expresiion pour créer un nouveau StringArray avec une taille définie.

    String [] stringArray = stream.toArray (size-> new String [size]);

  2. Utilisation directe de la référence de méthode.

    String [] stringArray = stream.toArray (String [] :: new);

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.