2017-01-30 26 views
4

我试图想办法做到这一点,而不必调用stream()两次,但都无济于事:使用流映射收取结果

List<Song> songs = service.getSongs(); 

List<ArtistWithSongs> artistWithSongsList = songs.stream() 
    .collect(Collectors 
     .groupingBy(s -> s.getArtist(), Collectors.toList())) 
    .entrySet() 
    .stream() 
    .map(as -> new ArtistWithSongs(as.getKey(), as.getValue())) 
    .collect(Collectors.toList()); 

按照要求:

class ArtistWithSongs { 
    private Artist artist; 
    private List<Song> songs; 

    ArtistWithSongs(Artist artist, List<Song> songs) { 
     this.artist = artist; 
     this.songs = songs; 
    } 
} 

是否有更好的做法呢?

+1

你可以发布你的'ArtistWithSongs'类吗? – shmosel

+2

我怀疑是否可以对流的元素进行分组而不收集它们。 –

+0

没有获得者或接受者?它应该是不可变的吗? – shmosel

回答

-1

我认为你可以使用FlatMap:

List<Song> songs = service.getSongs(); 

List<ArtistWithSongs> artistWithSongsList = songs.stream() 
       .collect(Collectors 
       .groupingBy(s -> s.getArtist(), Collectors.toList())) 
       .entrySet() 
       .flatMap(as -> new ArtistWithSongs(as.getKey(), as.getValue())) 
       .collect(Collectors.toList()); 

编辑:

抱歉,我们无法收集后用flatMap( ),因为它不会返回流。其他解决方案是:

List<ArtistWithSongs> artistWithSongsList = new ArrayList<>(); 
    songs.stream() 
     .collect(Collectors.groupingBy(Song::getArtist)) 
     .forEach((artist, songs) -> artistWithSongsList.add(new ArtistWithSongs(artist, songs));); 
+0

你不能调用'Set'上的'flatMap',你有没有在某处省略'.stream()? – MikaelF

0

我想用的forEach足够在这种情况下:

List<ArtistWithSongs> artistWithSongsList = new ArrayList<>(); 
service.getSongs().stream() 
        .collect(Collectors.groupingBy(s -> s.getArtist(), Collectors.toList())) 
        .entrySet() 
        .forEach((k, v) -> artistWithSongsList.add(new ArtistWithSongs(k, v)););