• Post Reply Bookmark Topic Watch Topic
  • New Topic

Question in Java8 Stream .map

 
Yuen Lian Wu
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi All,

I am new to Java8 Stream operation. Basically I want to simplify my line of codes in Java8 by exactly knowing the behaviour and limit of .map operation.

I have a list of trade objects called activities which contain name/ID of the stock, quantity and name of the holder. It might be same holder on same instrument multiple time due to different trade executions in a day.
I want to sum of all the quantities aggregated by stock ID and Holder. During my streaming operation I would like to put the aggregated result in another enriched object called AggregatedTrade object which it have almost identical data structure as the Trade object itself.

Code Snippet
--------------



As you can see, I don't know much about Streaming. I split the process into 2. First aggregated into it's own object then use another for loop to populate into my enriched object.

In fact, can I use stream to achieve group by in single operation? Meaning I can looping thru Trade object and directly populate aggregated result into AggregatedTrade object in 1 shot.


Let me know, Thanks.

Foritude
 
Campbell Ritchie
Marshal
Posts: 52581
119
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch

I have added code tags to your post and some indentation and doesn't it look better Always use the tags.

It is difficult to tell what is happening because you appear to start with a stream field (line 1). Do you mean stream()? Please copy and paste code which actually runs so we aren't getting confused by any syntax errors. I can see other errors, e.g. unmatched () pairs. Please also tell us what the methods do; you have a get() method and we don't know what that does.

So line 1 (which should really be broken into two, one for each call) creates a Stream. What from? Is it a List?
Look up the Collectors#groupingBy method when applied to Stream#collect returns a Map.
So at the end of line 1 you have a Map.
I think at this point you should print the value returned from line 1 and see what happens. You should have a Map with holder catenated to ID as its “K”. Is such a Map part of what you want?

Also please write down in simple terms what your desired endpoint is. If you had a List of Trades, how would you instruct somebody to get what you want?
What are you trying to get out of the entry set in line 3? Can you get a Stream out of the value? Does that line compile?

Have you read the documentation for the Stream#map method? It creates a new Stream by taking the elements of the old stream and getting some sort of attribute from them and creating a Stream of the type of that attribute.
 
Yuen Lian Wu
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you for your attention CampBell. The original code looks like following. I was trying to have 1 block of code doing everything(the commented part) but it doesn't work and have syntax error

List<SweepActivity> aggregatedActivities = activities.stream()
.collect(Collectors.groupingBy(sa -> sa.getClientBookID() + sa.getImntID() + sa.getExchangeID()))
.entrySet().stream()
.map(e -> e.getValue().stream()
.reduce((f1, f2) -> new SweepActivityImpl(SweepActivity.EventType.AGGREGATED.name(), f1.getClientBookID(), null, null, null, null,
f1.getImntID(), f1.getPrice(), f1.getRIC(), f1.getInstrumentType(), f1.getExchangeID(), f1.getCountryOfRegistration(), f1.getTradeCurrency(),
f1.getQuantity().add(f2.getQuantity()), f1.getSweepDate())))
.map(f -> f.get())
.collect(Collectors.toList());


// List<PositionSweep> aggregatedActivities = activities.stream()
// .collect(Collectors.groupingBy(sa -> sa.getClientBookID() + sa.getImntID() + sa.getExchangeID()))
// .entrySet().stream()
// .map(e -> e.getValue().stream()
// .reduce((f1, f2) -> new PositionSweepImpl(f1.getClientBookID(), f1.getImntID(), f1.getRIC(), f1.getInstrumentType(), null,
// f1.getExchangeID(), f1.getTradeCurrency(), f1.getQuantity().add(f2.getQuantity()), null, f1.getSweepDate())))
// .map(f -> f.get())
// .collect(Collectors.toList(PositionSweep));

//Populate into PositionSweep object. Will think about how to utilize Stream process to remove this part
List<PositionSweep> positionSweeps = new ArrayList<PositionSweep>();
for (SweepActivity activity:aggregatedActivities) {
PositionSweep ps = new PositionSweepImpl(activity.getClientBookID(), instrument, buySellType.name(),
activity.getTradeCurrency(), activity.getQuantity(), activity.getPrice(), activity.getSweepDate());

positionSweeps.add(ps);
}
 
Yuen Lian Wu
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Campbell for your reminder. I have changed my name.

My general purpose is to have one operation does the aggregation and populate the result into list of enriched objects. Little bit like the following example from Oracle, but will aggregated into a list instead.

 
Yuen Lian Wu
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Fortitude cooL wrote:Thank you for your attention CampBell. The original code looks like following. I was trying to have 1 block of code doing everything(the commented part) but it doesn't work and have syntax error

 
Campbell Ritchie
Marshal
Posts: 52581
119
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think you are going to have to go through it bit by bit. Start with your stream. To get back to your original post, start with the first line and print it.
List<Trade> aggregatedActivities = activities.stream.collect(Collectors.groupingBy(a -> a.getHolder() + a.getStockID()))
.entrySet().stream()…

System.out.println(activities.stream());
I am pretty sure you missed out a pair of () which I have marked in red. You won't get a lot from that, but you will get an output. Streams don't override Object#toString(), so you won't get an informative printout. If you want any more than that, change that to
activities.stream().forEach(System.out::println);
Now add the second stage (.collect(...)) and print that out. You will see what is happening to the Stream/Streams as you go. You will also be able to see what compiles and what won't.

Decide what your endpoint is, and see how you are working towards that. Add ore code, but by bit and print it with either of the versions I showed (both use System.out.println somewhere). You will probably get there by adding little bits at a time and testing them all as you go.

You have a difficult task getting all that lot to work if you aren't experienced with Streams. Have you been through the Java Tutorials and seen how Streams work with collections? Have you been through the Stream documentation, because some of the methods have examples shown?
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!