Options to accumulate from a List without an intermediate

Brian Goetz brian.goetz at oracle.com
Fri Jan 4 19:53:02 PST 2013


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