我一直在写一个程序,将采取一系列的音乐文件的名称和播放他们。我成功地做到了这一点,但是,我想改进一些东西,让它变得更好一点。我试图使音乐播放在一个随机的顺序,但不重复任何歌曲之前,整个名单已经播放。我几乎可以做到这一点,但我认为有一些问题,我做而循环。程序按预期运行大约8首歌曲,但随后停止播放音乐,jvm继续运行。我使用bluej,因为我仍然是ap comp sci的学生,所以我意识到我可能无法完成这项任务,但任何帮助都将不胜感激。我有一个驱动程序“musicdriver”,它与另外两个类“mp3”和“music”有“has-a”关系。
我的mp3课程:
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import javazoom.jl.player.Player;
public class MP3 {
String filename;
Player player;
public void stopMP3() { if (player != null) player.close(); }
// play the MP3 file to the sound card
public void playMP3(String filename) {
try {
FileInputStream fis = new FileInputStream(filename);
BufferedInputStream bis = new BufferedInputStream(fis);
player = new Player(bis);
}
catch (Exception e) {
System.out.println("Problem playing file " + filename);
System.out.println(e);
}
// run in new thread to play in background
new Thread() {
public void run() {
try { player.play(); }
catch (Exception e) { System.out.println(e); }
}
}.start();
}
}
我的音乐课:
import java.util.*;
public class Music{
private ArrayList<String> music;
public Music(){music = new ArrayList<String>();}
public int size(){return music.size();}
public void addSong(String song){music.add(song);}
public String getSong(){return music.get(music.size());}
public String getSong(int num){return music.get(num);}
public void removeSong(String song){
for(int i = 0; i < music.size(); i++){
if(music.get(i).equals(song)) {music.remove(i); return;}
}
}
public String toString(){
String s = "";
for(int i = 0; i < music.size(); i++){
s += music.get(i);
}
return s;
}
}
我的音乐课:
import java.util.*;
import java.io.*;
import javazoom.jl.player.Player;
import java.util.Random;
import java.util.Scanner;
import java.io.FileNotFoundException;
public class MusicDriver{
public static void main(String[] args) throws FileNotFoundException{
Random r = new Random();
Scanner s = new Scanner(System.in);
String line = "";
int number;
Music song = new Music();
song.addSong("1-01-overture.mp3");
song.addSong("1-03-fortune-teller-2.mp3");
song.addSong("1-07-prayer.mp3");
song.addSong("1-08-island-atlas.mp3");
song.addSong("1-12-warren-report.mp3");
song.addSong("1-13-avilla-hanya.mp3");
song.addSong("1-20-war-situation.mp3");
song.addSong("2-10-fog-of-phantom.mp3");
song.addSong("2-12-religious-precepts.mp3");
song.addSong("2-14-box-of-sentiment.mp3");
song.addSong("3-02-light-everlasting.mp3");
song.addSong("3-09-viking-spirits.mp3");
song.addSong("3-12-unsealed.mp3");
song.addSong("3-16-notice-of-death-reprise-.mp3");
//14 songs
ArrayList<Integer> songNums = new ArrayList<Integer>();
MP3 mp3 = new MP3();
do{
if(songNums.size() == song.size()) songNums.clear();
number = r.nextInt(song.size());
boolean done = false;
int counter = 0;
while(!done){
for(int i = 0; i < songNums.size(); i++){
if(number == songNums.get(i).intValue()) {number = r.nextInt(song.size()); counter++;}
}
if(counter == 0) done = true;
else done = false;
}
songNums.add(number);
mp3.playMP3(song.getSong(number));
System.out.println("Now Playing " + song.getSong(number));
System.out.println("Enter \"Stop\" to stop playing the song");
System.out.println("Enter \"n\" to play the next song");
line = s.nextLine();
mp3.stopMP3();
}while(line.equals("n"));
mp3.stopMP3();
}
}
我做了很多研究,为什么我的程序只是停止播放我的歌曲,但我没有找到任何东西。我发现,如果你在输出之前请求输入,bluej程序不会打开终端窗口(当你执行“system.out.print()”时会出现这种情况),但我认为这个程序没有考虑到这一点。我还确保在播放下一首歌时输入了一个字符串“n”,对于前几首歌,它可以工作,但在第八首歌之后,它就停止了。我完全糊涂了。
4条答案
按热度按时间sg24os4d1#
我认为唯一的问题在于你用来洗牌列表的逻辑。
当生成的随机数已经存在于songnums列表中时,您将生成一个新的随机数。这个新的随机数并没有与songnums列表中的所有数字一起检查。下面的更改应该可以解决您的问题。
或者,您可以在注解中使用sasha的建议来洗牌列表(collections.shuffle())。
pcrecxhr2#
现有算法的实际问题是没有重置
counter
当你发现一首已经播放过的歌曲时。所以一旦你重复一次,你就会陷入一个无限循环-done
永远不会是真的。(实际上,它不会是无限的——一次
counter
达到Integer.MAX_VALUE
它会绕到Integer.MIN_VALUE
最终达到0
再说一次,如果你把它放得足够长,它最终会播放另一首歌)关于代码的改进,这里已经有一些有用的建议,我不在这里重复了,但是最基本的修改是移动代码的初始化
counter
至0
循环内部:lstz6jyr3#
sasha在评论中说:使用collections.shuffle()。实际上,这看起来像是这样:
在音乐课上,我们有一个方法来获取所有歌曲:
musicdriver中的循环将沿着以下线路:
在一个变量命名注解中,将music类的示例命名为“song”(单数)有点混乱。也许叫它“音乐”或者至少叫“歌曲”。
vddsk6oq4#
我要做的是: