6
votes

Utilisation de la même liste avec des flux deux fois en Java

Je dois compléter cette opération triviale avec des flux: donnée une liste, obtenir la somme et la somme des 20 premiers éléments.

C'est ce que j'avais à l'esprit xxx

Cependant, je ne peux pas faire cela, car je me dis que je ne peux pas réutiliser un ruisseau, alors j'ai essayé ce qui suit: xxx

Cependant, je suis dit que Je ne peux pas utiliser la somme sur le flux, alors j'ai besoin de mapper à nouveau pour la main gauche et droite de cette opération triviale.

est là un moyen de faire cette opération de manière plus élégante et concise à l'aide de flux ?


4 commentaires

Avec ces contraintes, cela ressemble à la manière la plus élégante, c'est avec un bon 'OL pour boucle.


Vous pouvez écrire un collateur personnalisé ...


Juste obtenir le flux deux fois de la liste; avec un avec une limite. Il n'est pas nécessaire de surcharger des choses (collectionneur personnalisée ou autre) quand il peut être simple ...


Je pense que c'est assez stupide de répéter le Maptoint deux fois, non?


3 Réponses :


6
votes

au lieu de collecter les chiffres dans une liste code>, vous pouvez les transformer en un int [] code> avec toarray () code>. De cette façon, le code est un peu plus compact, vous n'avez pas à encadrer et à consigner tout le temps, et vous pouvez transformer ce int [] code> directement dans un intestream code> .

int[] nums = obj.stream().mapToInt(d -> d.getInt()).toArray();
IntStream.of(nums).limit(20).sum() / IntStream.of(nums).sum();


1 commentaires

Ceci peut également être généralisé à des nombres beaucoup plus gros que 20 (lors de l'évitant le double travail devient important) de sorte que vous stockiez la somme "tête" dans une variable, puis utilisez flux.skip (n) .sum () résumer le reste. Skip sera O (1) sur un tableau. Gardez simplement à l'esprit que Skip et limite ne pas paralléliser. Dans ce cas, Arrays.stream (tableau, décalage, limite) serait le meilleur choix.



3
votes

Il n'y a pas besoin de surcharger des choses. Obtenez simplement le flux à deux reprises de la liste:

List<Integer> obj = Stream.iterate(0, x -> x + 1).limit(5).collect(toList()); //[0, 1, 2, 3, 4]
Integer[] result = IntStream.range(0, obj.size())
                            .boxed()
                            .collect(limitSum(4, obj));
System.out.println(Arrays.toString(result)); //[10, 6]


0 commentaires

9
votes

Il y a une façon cool de le faire en une seule passe parallèle, mais pas d'utilisation de flux.

int[] nums = obj.stream().mapToInt(Integer::intValue).toArray();
Arrays.parallelPrefix(nums, Integer::sum);
int sumOfFirst20 = nums[19];
int sumOfAll = nums[nums.length-1];


0 commentaires