Options to accumulate from a List without an intermediate
Arul Dhesiaseelan
aruld at acm.org
Fri Jan 4 21:10:31 PST 2013
Excellent!
Here are the working versions. I had to cast to MultiFunction<Album, Track>
and apply Accumulators.<Track, Integer> before groupBy to break cyclic
inference, as it failed to compile because of java: incompatible types:
Cannot instantiate inference variables T because of an inference loop.
#1
final List<Track> tracks = albums.stream().mapMulti((MultiFunction<Album,
Track>) (collector, element) -> collector.yield(element.tracks)).into(new
ArrayList<Track>());
#2
Map<Integer, Collection<Track>> tracksByRating =
albums.stream().mapMulti((MultiFunction<Album, Track>) (collector, element)
-> collector.yield(element.tracks)).accumulate(Accumulators.<Track,
Integer>groupBy(Track::getRating));
Thanks Brian!
On Fri, Jan 4, 2013 at 5:53 PM, Brian Goetz <brian.goetz at oracle.com> wrote:
> Currently you can do:
>
> albums.stream()
> .mapMulti((d, a) -> d.yield(a.tracks))
> .into(new ArrayList<>());
>
> It is likely into() is replaced with some sort of aggregate:
>
> albums.stream()
> .mapMulti((d, a) -> d.yield(a.tracks))
> .aggregate(intoList());
>
> which covers your first case.
>
> To group by rating, you can do:
>
> Map<Integer, Collection<Track>>
> albums.stream()
> .mapMulti((d, a) -> d.yield(a.tracks))
> .accumulate(groupBy(Track::getRating));
>
>
>
> On 1/4/2013 10:19 PM, Arul Dhesiaseelan wrote:
>
>> Is there a better way to accumulate tracks from an album, without using an
>> intermediate?
>>
>> Take1 uses an intermediate, while Take2 does not use one, but more
>> verbose.
>> May be there is a better way?
>>
>> Take#1
>> final List<Track> tracks = new ArrayList<>();
>> albums.stream().forEach(album -> tracks.addAll(album.tracks));
>>
>> // Group album tracks by rating
>> Map<Integer, Collection<Track>> tracksByRating =
>> tracks.stream().accumulate(Accumulators.<Track,
>> Integer>groupBy(Track::getRating));
>>
>> Take#2
>> Map<Integer, Collection<Track>> tracksByRating =
>> albums.stream().accumulate(new Accumulator<Album, List<Track>>() {
>> @Override
>> public List<Track> makeResult() {
>> return new ArrayList<>();
>> }
>>
>> @Override
>> public void accumulate(List<Track> result, Album value) {
>> result.addAll(value.tracks);
>> }
>>
>> @Override
>> public List<Track> combine(List<Track> result, List<Track> other) {
>> return Streams.concat(result.stream(), other.stream()).into(new
>> ArrayList<Track>());
>> }
>> }).stream().accumulate(Accumulators.<Track,
>> Integer>groupBy(Track::getRating));
>>
>>
>> Thanks!
>> Arul
>>
>>
More information about the lambda-dev
mailing list