I am creating a music player app. I retrieve the data from the directory in a class named SongInfo which looks like this:
public class SongInfo {
//id of song
private long _ID;
//song name
private String title;
//artist name
private String artistName;
//album name
private String albumName;
//song duration
long duration;
//year of release
private String year;
//constructor
//comparators to sort data
My app has a structure such that there is a
ArtistsFragment to show the List of Artists on clicking -> it Opens up Albums Fragment which has the List of Albums of the selected artist -> opens up Songs Fragment which has ArrayList of Songs of the selected album. What I end up doing instead is create a data structure of this sort:
//contains most of the info of the song
ArrayList<SongInfo> songs;
//contains an arrayList of songs
ArrayList<ArrayList<SongInfo>> albums;
//contains an arraylist of albums
Arraylist<ArrayList<ArrayList<SongInfo>>> artists;
which I am very sure is the wrong way to do it, cos what if I had more layers? I am looking for a better way to do this. I just need a hint, but an illustration/explanation would be awesome. Thanks :)
Suppose we start with these classes:
public static class Song
{
String title;
Artist artist;
Album album;
Song( String title, Artist artist, Album album )
{ this.title = title; this.artist = artist; this.album = album; }
@Override public String toString() { return "Song: " + title; }
}
public static class Artist
{
String name;
Artist( String name ) { this.name = name; }
@Override public String toString() { return "Artist: " + name; }
}
public static class Album
{
String name;
Album( String name ) { this.name = name; }
@Override public String toString() { return "Album: " + name; }
}
Where:
Song
is what you are now calling with the rather unfortunate name SongInfo
Artist
is a class that you don't have yet, but you should. If you can't handle that, then whenever you see Artist
just think of a String
with an artist's name in it. Album
is another class that you don't have yet, but you should. If you can't handle that, then whenever you see Album
just think of a String
with an album's title in it. And suppose we start with this dataset:
Artist artist1 = new Artist( "Artist1" );
Artist artist2 = new Artist( "Artist2" );
Set<Artist> artists = new HashSet<>( Arrays.asList( artist1, artist2 ) );
Album album1 = new Album( "Album1" );
Album album2 = new Album( "Album2" );
Set<Album> albums = new HashSet<>( Arrays.asList( album1, album2 ) );
Song song11a = new Song( "Song11a", artist1, album1 );
Song song11b = new Song( "Song11b", artist1, album1 );
Song song22a = new Song( "Song22a", artist2, album2 );
Song song22b = new Song( "Song22b", artist2, album2 );
List<Song> songs = Arrays.asList( song11a, song11b, song22a, song22b );
Then the following will give you what you want:
Collection<Song> getSongsByArtist( Collection<Song> songs, Artist artist )
{
return songs.stream().filter( song -> song.artist == artist )
.collect( Collectors.toList() );
}
Collection<Album> getAlbumsByArtist( Collection<Song> songs, Artist artist )
{
return songs.stream().filter( song -> song.artist == artist )
.map( song -> song.album ).collect( Collectors.toSet() );
}
And the following will give you everything you always wanted to know about your dataset but were afraid to ask:
Map<Song,Artist> artistsBySong = songs.stream()
.collect( Collectors.toMap( Function.identity(), song -> song.artist ) );
Map<Song,Album> albumsBySong = songs.stream()
.collect( Collectors.toMap( Function.identity(), song -> song.album ) );
Map<Artist,List<Song>> songsByArtist = songs.stream()
.collect( Collectors.groupingBy( song -> song.artist ) );
Map<Album,List<Song>> songsByAlbum = songs.stream()
.collect( Collectors.groupingBy( song -> song.album ) );
assert songs.stream().map( song -> song.album )
.collect( Collectors.toSet() ).equals( albums );
assert songsByAlbum.keySet().equals( albums );
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.