Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #33971 > unrolled thread
| Started by | Rhino <no_offline_contact@example.com> |
|---|---|
| First post | 2016-03-15 14:11 -0400 |
| Last post | 2016-03-16 00:44 -0400 |
| Articles | 3 — 2 participants |
Back to article view | Back to comp.lang.java.programmer
Stream question Rhino <no_offline_contact@example.com> - 2016-03-15 14:11 -0400
Re: Stream question Sebastian <news@seyweiler.dyndns.org> - 2016-03-15 21:21 +0100
Re: Stream question Rhino <no_offline_contact@example.com> - 2016-03-16 00:44 -0400
| From | Rhino <no_offline_contact@example.com> |
|---|---|
| Date | 2016-03-15 14:11 -0400 |
| Subject | Stream question |
| Message-ID | <nc9j3k$orv$1@dont-email.me> |
I'm new to streams but very intrigued with the possibilities. I'm trying to write a stream that does grouping, counting and summing at the same time. The data involved is actually quite simple but writing the streaming statement I need is proving challenging and I'm not seeing anything really helpful in Google searches. First, let me describe my data, then I'll show you how I've solved two-thirds of the problem. Perhaps you can tell me how to fit in the missing piece. The data is ticket sales from a company that sells concert tickets. Each sale consists of an agency code, an order number, order date and the number of tickets sold. Therefore, it looks like this: AgencyCode OrderNumber OrderDate TicketsSold ---------- ----------- --------- ----------- TW 111111 2016-03-01 4 TW 111112 2016-03-01 2 CP 201000 2016-03-01 3 TW 111113 2016-03-01 8 CP 201001 2016-03-02 2 EL 300001 2016-03-01 4 AS 400000 2016-03-02 2 What I'm trying to get out of this data is a summary showing the total number of orders for each agency code and the total number of tickets sold for that same agency code. Therefore, the values I want to get for this particular set of data is: AgencyCode Orders TicketsSold TW 3 14 CP 2 5 EL 1 4 AS 1 2 I've got the grouping working and also the number of tickets sold. It's just the counting of the orders that I'm trying to get. Here's how I got the tickets sold by agency: Map<String, Integer> salesByAgency = ticketOrders.stream() .collect(Collectors.groupingBy(TicketSale::getAgencyCode, Collectors.summingInt(TicketSale::getTicketsSold))); TicketSale is the class that holds a single ticket order. My collection, ticketOrders, is a LinkedHashSet holding a bunch of TicketSale records. How do I adjust what I have to get the number of orders for each agency code? -- Rhino
[toc] | [next] | [standalone]
| From | Sebastian <news@seyweiler.dyndns.org> |
|---|---|
| Date | 2016-03-15 21:21 +0100 |
| Message-ID | <nc9qt2$h0t$1@news.albasani.net> |
| In reply to | #33971 |
Am 15.03.2016 19:11, schrieb Rhino:
[example snipped]
>
> How do I adjust what I have to get the number of orders for each agency
> code?
>
Two possibilities come to my mind.
(A) This answers your question of how to adjust what you have.
On Feb 22nd I posted in this group in the thread "stream filter twice",
see
https://groups.google.com/d/msg/comp.lang.java.programmer/zSqNcCNDCRI/mmeBA3w0DQAJ
In that post I discuss the possibility of using a so-called "combining
collector" from the library jool (https://github.com/jOOQ/jOOL). In your
case, such a collector would apply two downstream collectors
simultaneously and return a pair of results:
// untested
Map<String, Tuple2<Integer, Long>> salesByAgency
= ticketOrders.stream()
.collect(groupingBy(TicketSale::getAgencyCode,
Tuple.collectors(
summingInt(TicketSale::getTicketsSold),
counting())));
If you don't want the dependency on the library, it is easy to write the
collector yourself, see the post cited.
Notes:
1. Questions like this involving processing data from the same stream
source multiple times in different ways come up very often. Jool
provides a very neat way to deal with this need. Excellent library.
2. Besides summing, you can also do any other reduction using
Collectors.reducing() as one of the downstream collectors.
(B) This does not adjust what you have, but is a different (and much
simpler) way to do it.
Map<String, IntSummaryStatistics> salesByAgency
= ticketOrders.stream()
.collect(groupingBy(TicketSale::getAgencyCode,
Collectors.summarizingInt(TicketSale::getTicketsSold)));
IntSummaryStatistics has methods getCount() and getSum().
-- Sebastian
[toc] | [prev] | [next] | [standalone]
| From | Rhino <no_offline_contact@example.com> |
|---|---|
| Date | 2016-03-16 00:44 -0400 |
| Message-ID | <ncao76$ovj$1@dont-email.me> |
| In reply to | #33975 |
On 3/15/2016 4:21 PM, Sebastian wrote: > Am 15.03.2016 19:11, schrieb Rhino: > [example snipped] >> >> How do I adjust what I have to get the number of orders for each agency >> code? >> > > Two possibilities come to my mind. > > (A) This answers your question of how to adjust what you have. > > On Feb 22nd I posted in this group in the thread "stream filter twice", > see > https://groups.google.com/d/msg/comp.lang.java.programmer/zSqNcCNDCRI/mmeBA3w0DQAJ > > > In that post I discuss the possibility of using a so-called "combining > collector" from the library jool (https://github.com/jOOQ/jOOL). In your > case, such a collector would apply two downstream collectors > simultaneously and return a pair of results: > > // untested > Map<String, Tuple2<Integer, Long>> salesByAgency > = ticketOrders.stream() > .collect(groupingBy(TicketSale::getAgencyCode, > Tuple.collectors( > summingInt(TicketSale::getTicketsSold), > counting()))); > > If you don't want the dependency on the library, it is easy to write the > collector yourself, see the post cited. > > Notes: > 1. Questions like this involving processing data from the same stream > source multiple times in different ways come up very often. Jool > provides a very neat way to deal with this need. Excellent library. > > 2. Besides summing, you can also do any other reduction using > Collectors.reducing() as one of the downstream collectors. > I have to admit I'm not keen on using an extra library. It just seems like something else to learn. (And maintain. And install everywhere my program runs.) I'm sure it's as great a library as you say it is but your second solution is the one I prefer, at least so far. As I learn more, I may develop a preference for Jool ;-) > > (B) This does not adjust what you have, but is a different (and much > simpler) way to do it. > > Map<String, IntSummaryStatistics> salesByAgency > = ticketOrders.stream() > .collect(groupingBy(TicketSale::getAgencyCode, > Collectors.summarizingInt(TicketSale::getTicketsSold))); > > IntSummaryStatistics has methods getCount() and getSum(). I really like this! It's nice and simple to look at and when I ran it in debug, it worked very nicely and produced the result I wanted. The only negative is that it returns two statistics that I don't need and I'm probably paying something for that but the volumes of data I am processing are very low so I don't see any extra expense as significant. (It might be if I were processing millions of records but I'm only going to have dozens most of the time.) Thank you VERY much for this solution! I've got a lot to learn but this will help me get off to a good start as I try to understand streams and stream handling. -- Rhino
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.java.programmer
csiph-web