Java 8 peek vs carte
J'ai le cas suivant: il y a une liste d'objets - ProductData qui contient plusieurs champs:
public class ProductData
{
....
private String name;
private String xref;
//getters
//setters
}
et il y a de l'API qui retourne la liste des objets suivants:
public class RatingTableRow
{
private String planName;
private String planXref;
private int fromAge;
private int toAge;
private int ratingRegion;
//constructor
//getters
//setters
}
mais il renvoie des objets vides champ nom du plan, car il n'est pas permis, lors de l'extraction de cet objet. J'ai besoin de lien de données du produit avec RatingTableRow par le xref afin de définir un nom dans le RatingTableRow parce que j'ai besoin pour utiliser cet objet, plus tard, j'ai donc créé à la suite du code pour le faire:
Map<String, ProductData> productByXref = plans.stream()
.collect(toMap(ProductData::getInternalCode, Function.identity()));
return getRatingTableRows(...).stream
.filter(ratingRow -> productByXref.containsKey(ratingRow.getPlanXref()))
.peek(row -> {
ProductData product = productByXref.get(row.getPlanXref());
row.setPlanName(product.getName());
})....;
Je sais que java docs disent que peek
ne convient pas à ces besoins, mais que vous voulez obtenir vos suggestions sur la façon d'effectuer cette tâche en plus de façon correcte.
- Que diriez -
map
ouforEach
etreturn row;
dans la fonction? - Si vous souhaitez modifier des objets existants, je pense que
foreach
est le meilleur choix. - pouvez-vous expliquer pourquoi foreach est le mieux pour cette tâche?
- Parce que
foreach
s'applique un peu de code pour chaque élément de la liste, un peu comme un vieux stylefor
en boucle. Mais je viens de remarquer ceux...
aprèspeek
; est-il plus du stream?foreach
est un terminal de flux de l'opération, dans ce cas,peek
pourrait en effet être la meilleure façon. BTW, c'est quoi la méthode censéreturn
? - Euh, je ne pense pas que l'œil est mauvais ici. carte non plus.
- ... mais encore une fois, dans ce cas, vous pourriez vouloir diviser le flux. Réglez d'abord le plan de noms avec
foreach
, et puis lisez à nouveau sur la liste fixe et de faire tout ce qui s'en vient. Notez que maintenant, tout ce qui vient aprèspeek
également être appliqués que sur les éléments qui passent à lafilter
. Vous ne savez pas si c'est volontaire. - En fait, j'ai utilisé ce code comme certains l'API pour une autre partie de l'application et de la faire revenir flot des nouvelles de filtrage/carte chaînes peuvent être ajoutées.
- Peut-être que vous devriez nous dire: pourquoi avez-vous choisi d'utiliser
peek
, en dépit de l'avertissement dans la documentation, au lieu d'utiliser le terminal de l'opérationforEach
qui est la bonne manière d'appliquer une opération à chaque élément d'un flux. Quels sont vos besoins, que ce code ne nous dites pas que. - Donc, comme je l'ai mentionné plus tôt, je l'ai utilisé dans certains autres endroits, et a décidé de flux retour. Dans un autre endroit, j'ai ajouté le filtrage d'appel donc, actuellement, il ressemble à une chaîne d'exécutions.
Vous devez vous connecter pour publier un commentaire.
Il y a une raison
peek
est documenté pour être principalement à des fins de débogage.Quelque chose qui finit par être traitées à l'intérieur de
peek
pourraient ne pas être admissibles pour le fonctionnement du terminal à tous et les ruisseaux sont exécutés uniquement par un terminal d'opération.Supposons qu'un exemple trivial d'abord:
Tout a l'air bien droit? Parce que
peek
sera exécuté pour tous les éléments dans ce cas. Mais qu'advient-il lorsque vous ajoutez unfilter
(et oublier ce quepeek
n'):L'exécution d'
peek
pour chaque élément, mais la collecte aucune. - Vous sûr de vouloir ça?Cela peut devenir encore plus difficile:
Dans java 8 la liste est remplie, mais dans le jdk-9
peek
n'est pas appelée à tous. Puisque vous n'êtes pas à l'aide defilter
ouflatmap
vous n'êtes pas modifier la taille de la rivière et decount
seuls besoins de sa taille; donc peek n'est pas appelée à tous les. Ainsi, en s'appuyant surpeek
est une très mauvaise stratégie.map
s avecpeek
s.map
était de retour le même objet, il en avait marre. IntelliJ juste ne le savais pas que j'étais le modifiant dans le temps.peek
s si il pense que vous n'êtes pas en train de les utiliser.map
assure que l'opération a lieu quel que soit. Vous ne savez pas si c'est ce que vous vous demandez si.map
. Je pense qu'il n'a rien à voir avec ça,peek
pouvez obtenir sauté indépendamment de la modification.map()
méthode est censé être libre de les effets secondaires et vous êtes de retour le même objet? C'était au moins le cas pour moi.You are executing peek for every element, but collecting none. You sure you want that?
Je ne comprends pas pourquoi c'est un problème, le peek est avant le filtre, de sorte qu'il est prévu pour être exécuté pour chaque élément?