Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 peek vs map

Tags:

java

java-8

I have following case: there is a list of objects - ProductData which contains several fields:

public class ProductData { ....   private String name;   private String xref;    //getters   //setters } 

and there is API which returns list of following objects:

public class RatingTableRow {   private String planName;   private String planXref;   private int fromAge;   private int toAge;   private int ratingRegion;   //constructor  //getters  //setters  } 

but it returns objects with empty plan name field because it's not allowed during extraction of this object. I need to link product data with RatingTableRow by the xref in order to set plan name into the RatingTableRow because I need to use this object later so I created following code to do that:

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());         })....; 

I know that java docs say that peek doesn't fit these needs but want to get your suggestions on how to make this task in more correct way.

like image 967
Alex Avatar asked Jun 05 '17 13:06

Alex


People also ask

What is Peek () method in java8?

Java 8. Java Stream Basics, Java Stream Methods. Java Stream peek() method returns a new Stream consisting of all the elements from the original Stream after applying a given Consumer action.

What is the use of PEEK in Java?

peek() method in Java is used to retrieve or fetch the first element of the Stack or the element present at the top of the Stack. The element retrieved does not get deleted or removed from the Stack. Parameters: The method does not take any parameters.

What is difference between map () and flatMap () in java8?

map() function produces one output for one input value, whereas flatMap() function produces an arbitrary no of values as output (ie zero or more than zero) for each input value.

Why would you choose to use a peek operation instead of a forEach operation on a Stream?

peek can get the smallest item directly compared with stream. foreach().


Video Answer


1 Answers

There is a reason peek is documented to be mainly for debugging purposes.

Something that ends up being processed inside peek might not be eligible for the terminal operation at all and streams are executed only by a terminal operation.

Suppose a trivial example first:

    List<Integer> list = new ArrayList<>();     List<Integer> result = Stream.of(1, 2, 3, 4)             .peek(x -> list.add(x))             .map(x -> x * 2)             .collect(Collectors.toList());      System.out.println(list);     System.out.println(result); 

Everything looks fine right? Because peek will run for all elements in this case. But what happens when you add a filter (and forget about what peek did):

 .peek(x -> list.add(x))  .map(x -> x * 2)  .filter(x -> x > 8) // you have inserted a filter here 

You are executing peek for every element, but collecting none. You sure you want that?

This can get even trickier:

    long howMany = Stream.of(1, 2, 3, 4)             .peek(x -> list.add(x))             .count();      System.out.println(list);     System.out.println(howMany); 

In java-8 the list is populated, but in jdk-9 peek is not called at all. Since you are not using filter or flatmap you are not modifying the size of the Stream and count only needs it's size; thus peek is not called at all. Thus relying on peek is a very bad strategy.

like image 68
Eugene Avatar answered Sep 22 '22 22:09

Eugene