Zetland
Zetland

Reputation: 567

How to tell if you've reached the end of a for-loop on an arraylist?

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

Answers (3)

Joey Chong
Joey Chong

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

muffin
muffin

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

jjlema
jjlema

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

Related Questions