Reputation: 567
I'm currently trying to build a playlist function which takes a music library and produces a random playlist from it, of a specified minimum duration. The idea is that it takes a minimum rating from a user - but, if there aren't enough tracks of that rating to fill the playlist, it goes for tracks of minimumRating - 1
. Thus, if you wanted 60 minutes of 5-star tracks, but you don't have enough, the program will try to fill the rest with 4-star ones.
So I need a way of decrementing the minimumRating
once it reaches the end of its for-loop, then setting it off again. Is there a method I can use which returns something (maybe a boolean) if the for-loop has reached its end?
In case it's helpful, my current code can be found here:
public ArrayList<Track> createPlaylist(int minRating, int minDuration) {
minDuration = minDuration * 60;
ArrayList<Track> shuffledList = trackList;
ArrayList<Track> playlist = new ArrayList<Track>();
Collections.shuffle(shuffledList);
int playlistDuration = 0;
while (playlistDuration < minDuration) {
for (Track track : shuffledList) {
if (track.getRating() >= minRating) {
playlist.add(track);
playlistDuration += track.getLength();
}
}
}
return playlist;
}
Upvotes: 0
Views: 873
Reputation: 1500
public ArrayList<Track> createPlaylist(int minRating, int minDuration) {
minDuration = minDuration * 60;
ArrayList<Track> sortedList = trackList;
ArrayList<Track> playlist = new ArrayList<Track>();
Collections.sort(sortedList, Collections.reverseOrder()); // implements comparable at rating
int playlistDuration = 0;
for (Track track : sortedList) {
playlist.add(track);
playlistDuration += track.getLength();
if (playlistDuration > minDuration)
break;
}
Collections.shuffle(playlist);
return playlist
}
Upvotes: 0
Reputation: 1486
The first thing that came into my mind is that you could make a class for Playlist:
public class Playlist {
private final List<Track> playlist = new ArrayList<Track>();
private int playlistDuration = 0;
public void addTrack(Track track) {
playlist.add(track);
playlistDuration += track.getLength();
}
public int getDuration() {
return playlistDuration;
}
public List<Track> getPlaylist() {
return playlist;
}
public void shufflePlaylist() {
Collections.shuffle(playlist);
}
}
You could spare a lot of lines in your code, your for-loop would look like this:
public ArrayList<Track> createPlaylist(int minRating, int minDuration) {
minDuration = minDuration * 60;
playlist.shufflePlaylist();
while (playlist.getDuration() < minDuration) {
for (Track track : trackList) {
if (track.getRating() >= minRating) {
playlist.addTrack(track);
}
if (playlist.getDuration() > minDuration) {
return;
}
}
}
return playlist;
}
Upvotes: 1
Reputation: 850
You can do something like this:
public ArrayList<Track> createPlaylist(final int minRating, int minDuration) {
minDuration = minDuration * 60;
final ArrayList<Track> shuffledList = trackList;
final ArrayList<Track> playlist = new ArrayList<Track>();
Collections.shuffle(shuffledList);
int playlistDuration = 0;
int myMin = minRating;
while (playlistDuration < minDuration && myMin > 0) {
for (final Track track : shuffledList) {
if (track.getRating() >= myMin && !playlist.contains(track)) {
playlist.add(track);
playlistDuration += track.getLength();
}
}
myMin--;
}
return playlist;
}
Upvotes: 1