为什么我的代码导致无限循环?

时间:2014-11-05 14:34:04

标签: java infinite-loop

我目前正在研究一种从音乐库创建播放列表的方法。这个想法是它要求歌曲的最低评级和播放列表的最小运行时间,然后产生符合这些标准的随机歌曲列表。如果没有足够的最低评级歌曲,则将评级降低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;

6 个答案:

答案 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对列表进行排序,则效率会更高。那么你只需要迭代一次音轨列表。