我目前正在研究一种从音乐库创建播放列表的方法。这个想法是它要求歌曲的最低评级和播放列表的最小运行时间,然后产生符合这些标准的随机歌曲列表。如果没有足够的最低评级歌曲,则将评级降低1,然后查找符合该要求的歌曲。 (因此,如果您指定播放列表应该有60分钟的5首星级歌曲,但是您没有足够的歌曲,那么它会尝试用其他时间填充4首星级歌曲。)
但是,如果我的库不包含5首星级歌曲,则会在我的代码中产生无限循环。 (或者我假设,无论如何,测试程序不会停止运行)为什么会这样?
public Playlist createPlaylist(int minRating, int minDuration) {
minDuration = minDuration * 60;
ArrayList<Track> shuffledList = trackList;
Playlist playlist = new Playlist();
Collections.shuffle(shuffledList);
int playlistDuration = 0;
while (playlistDuration <= minDuration) {
for (Track track : shuffledList) {
if (track.getRating() >= minRating && !playlist.contains(track))
{
playlist.add(track);
playlistDuration += track.getLength();
}
if (playlistDuration >= minDuration) {
break;
}
}
minRating--;
}
playlist.randomise();
return playlist;
答案 0 :(得分:4)
由于playlistDuration
有条件地更新,因此循环变为无限可能有很多原因。例如,如果shuffledList
为空,则playlistDuration
将保持为零,因此外部循环将是无限的。
如果您在进入循环之前将minDuration
调整为shuffledList
的总持续时间,则可以避免这种情况:
minDuration = Math.Min(minDuration, shuffledList.Sum(t => t.getLength()));
简单来说,这意味着&#34;我不能要求最短持续时间超过shuffledList
&#34;
您还应该将while
循环的条件更改为严格&#34;小于&#34;,否则当shuffledList
为空时,无限循环将保留。
while (playlistDuration < minDuration) {
...
}
答案 1 :(得分:1)
因为可以在不更改while
的情况下浏览playlistDuration
循环的正文;特别是,当你没有添加任何曲目时。
答案 2 :(得分:1)
像这样改变你的循环,在浏览了所有曲目并且评级== -1
时退出循环while (playlistDuration <= minDuration) {
for (Track track : shuffledList) {
if (track.getRating() >= minRating && !playlist.contains(track))
{
playlist.add(track);
playlistDuration += track.getLength();
}
if (playlistDuration > minDuration) {
break;
}
}
minRating--;
if (minRating == -1) break;
}
答案 3 :(得分:0)
如果您没有找到任何五星级歌曲,则不要更新playlistDuration
,因此您的while循环会一直持续。
答案 4 :(得分:0)
当没有足够的曲目来获取播放列表时,会发生什么? minDuration?
我的猜测是:
while( playListDuration <= minDuration )
跋涉。
因此,你可能想要在你的同时检查它,一个选项是添加跟踪存在的条件
PS:哇。键入几行时,发布3个答案,downvote,upvote。啧。答案 5 :(得分:0)
有几个问题
(1)如果歌曲的总持续时间太小,它将永远不会退出。您需要基于最低评级的退出条件。由于洗牌列表上的迭代器总是有限的,这将保证代码退出。
(2)平等似乎不匹配。如果它的最小持续时间==播放列表持续时间,它继续迭代,即使它没有添加任何轨道,这是浪费的。将while循环更改为严格小于。
(3)如果使用带有自定义比较器的treeSet对列表进行排序,则效率会更高。那么你只需要迭代一次音轨列表。