【问题标题】:creating a shuffle method for playlist in java在java中为播放列表创建一个随机播放方法
【发布时间】:2013-12-27 13:58:23
【问题描述】:

虽然下面的说明看起来很清楚,但我完全不知道如何实现这段代码。

当代音乐软件最流行的功能之一是能够随机化播放列表中歌曲的顺序——一种称为“随机播放”歌曲的动作。使用下面的伪代码作为指导创建一个 shuffle 方法:

create a new empty arraylist (called newList)

while (there are still songs left)

randomly select the index of one song on the playlist

remove it from the current playlist and place it at the end of newList

songs = newList

提示:使用 Java 库中的 Random 类生成一个随机数。它的方法是: 公共 int nextInt(int n)。 这将返回一个伪随机、均匀分布的 int 值,该值低至 0,高至 n。因此, nextInt(songs.size()) 给你一个随机索引。请记住,每次将随机选择的歌曲添加到 newList 时,歌曲的大小都会减少一首。每次生成随机数时都需要考虑这一点。

这就是我所拥有的导致程序崩溃的原因。我需要帮助从数组中检索歌曲、将其删除并将其放入新的数组列表中。请帮助我!

public int nextInt(int n) {

int index = randomGenerator.nextInt(songs.size());
              return index;
 }
public void shuffle (){
    newList = new ArrayList<Mp3> ();
    while (songs.size()>0){
        Mp3 song = songs.get(nextInt(songs.size()));
        newList.add(song);
        System.out.println("new list" + newList);
   }
 }

【问题讨论】:

  • 为什么不简单地使用 Collections.shuffle(list),它会为你打乱列表,然后遍历这个打乱的列表?也就是说,您需要两个列表:原始的、最初的完整列表,您将在每次迭代时从中随机挑选和删除一首歌曲,以及一个最初为空的列表,您将从第一个列表中随机挑选的歌曲填充.您忘记在代码中删除选择的歌曲。
  • @JBNizet 您只需要一个列表,因为“第二个”列表与您播放第一个列表的顺序相同。或者你保留一份清单,每次都重新洗牌。

标签: java arrays random


【解决方案1】:
import java.util.Random;

public class SuffleSongs {

    public static void main(String[] args) {

        List<String> playList = new ArrayList<String>();
        playList.add("Song1");
        playList.add("Song2");
        playList.add("Song3");
        playList.add("Song4");
        playList.add("Song5");
        playList.add("Song6");
        playList.add("Song7");
        playList.add("Song8");
        playList.add("Song9");
        playList.add("Song10");
        playList.add("Song11");
        playList.add("Song12");
        playList.add("Song13");
        playList.add("Song14");
        playList.add("Song15");
        playList.add("Song16");
        playList.add("Song17");
        playList.add("Song18");
        playList.add("Song19");
        playList.add("Song20");
        playList.add("Song21");

        // shuffle the playlist
        for (int i=0; i<playList.size(); ++i) {
            Random rand = new Random();
            int temp = rand.nextInt(playList.size() -i) + i;
            Collections.swap(playList, i, temp);
        }

        // print the shuffled playlist
        for(int j = 0; j < playList.size(); ++j) {
            System.out.println(playList.get(j));
        }

    }

}

这将随机播放,无需创建新的播放列表 (ArrayList)。
基本上这段代码只是获取一个播放列表 ArrayList,然后在同一个 ArrayList 中随机播放。

【讨论】:

  • 指令说:“随机选择播放列表中一首歌曲的索引,将其从当前播放列表中移除并放在newList的末尾”
  • @zac 循环可以以相反的顺序运行。相信代码还是可以参考的。
  • 循环的顺序并没有改变这是一个“交换 n 次”的事实,但是算法要求它通过随机移动每个项目来构建一个数组。您的算法中的项目很可能会保持在其初始位置。
【解决方案2】:

你在正确的轨道上,但你忘了实现描述的一步:

remove it from the current playlist and place it at the end of newList

方法Shuffle需要改写如下:

public void shuffle (){
    newList = new ArrayList<Mp3> ();
    while (songs.size()>0){
        Mp3 song = songs.get(nextInt(songs.size()));
        songs.remove(song); // the forgotten step
        newList.add(song);
        System.out.println("new list" + newList);
   }
 }

【讨论】:

    【解决方案3】:

    程序崩溃了,这是因为在你的shuffle方法中,while (songs.size()&gt;0){总是true列表大小不变。

    如果你想自己写一个shuffle方法,那么一个简单的方法是迭代歌曲列表交换当前索引为i的2首歌曲和带有a的歌曲随机索引

         public void shuffle (List<Mp3> songsList)
         {
             for(int i=0;i< songsList.size(); i++)
             {
                 //Do something here
                                  //generate a random number
                 //Swap songs according to the i index and and random index.
             }
         }
    

    最简单的方法是使用Collections#shuffle方法使列表随机化。

    Collections中shuffle对应的源码如下:

    /**
     * Randomly permutes the specified list using a default source of
     * randomness.  All permutations occur with approximately equal
     * likelihood.<p>
     *
     * The hedge "approximately" is used in the foregoing description because
     * default source of randomness is only approximately an unbiased source
     * of independently chosen bits. If it were a perfect source of randomly
     * chosen bits, then the algorithm would choose permutations with perfect
     * uniformity.<p>
     *
     * This implementation traverses the list backwards, from the last element
     * up to the second, repeatedly swapping a randomly selected element into
     * the "current position".  Elements are randomly selected from the
     * portion of the list that runs from the first element to the current
     * position, inclusive.<p>
     *
     * This method runs in linear time.  If the specified list does not
     * implement the {@link RandomAccess} interface and is large, this
     * implementation dumps the specified list into an array before shuffling
     * it, and dumps the shuffled array back into the list.  This avoids the
     * quadratic behavior that would result from shuffling a "sequential
     * access" list in place.
     *
     * @param  list the list to be shuffled.
     * @throws UnsupportedOperationException if the specified list or
     *         its list-iterator does not support the <tt>set</tt> method.
     */
    public static void shuffle(List<?> list) {
        shuffle(list, r);
    }
    

    【讨论】:

      猜你喜欢
      • 2023-01-23
      • 2014-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多