2016-03-28 21 views
8

Tôi đã viết một chương trình sẽ lấy một mảng tên của các tệp nhạc và phát chúng. Tôi đã thành công trong việc đó, nhưng, tôi muốn tiếp xúc với một số thứ và làm cho nó đẹp hơn một chút. Tôi đang cố gắng phát nhạc theo thứ tự ngẫu nhiên nhưng không lặp lại bất kỳ bài hát nào trước khi toàn bộ danh sách được phát. Tôi đã gần như có thể làm điều đó nhưng tôi nghĩ rằng có cái gì đó sai trái với vòng lặp do-while của tôi. Chương trình chạy như dự định cho khoảng tám bài hát nhưng sau đó nó ngừng phát nhạc và JVM tiếp tục chạy. Tôi đang sử dụng BlueJ vì tôi vẫn là một sinh viên AP Comp Sci nên tôi nhận ra rằng tôi không thể hoàn thành nhiệm vụ này nhưng bất kỳ sự trợ giúp nào cũng sẽ được đánh giá cao. Tôi có một trình điều khiển, "MusicDriver" là một mối quan hệ "có-một" với hai lớp khác: "MP3" và "Âm nhạc".Tại sao vòng lặp do-while không chạy như mong đợi trong chương trình Java này?

lớp MP3 của tôi:

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(); 
} 
} 

lớp Âm nhạc của tôi:

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; 
} 
} 

lớp MusicDriver tôi:

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(); 
} 
} 

Tôi đã làm rất nhiều nghiên cứu về lý do tại sao chương trình của tôi chỉ dừng lại chơi các bài hát của tôi nhưng tôi không thể tìm thấy bất cứ thứ gì. Tôi đã làm, thấy rằng các chương trình BlueJ không mở cửa sổ đầu cuối (điều xuất hiện khi bạn thực hiện một "System.out.print()") nếu bạn yêu cầu đầu vào trước khi bạn có bất kỳ đầu ra nào nhưng tôi không nghĩ có tính đến chương trình này. Tôi cũng đã đảm bảo rằng tôi đã nhập một chuỗi "n" khi tôi muốn phát bài hát tiếp theo và cho các bài hát đầu tiên, nó hoạt động, nhưng sau bài hát thứ tám, nó chỉ dừng lại. Tôi hoàn toàn bối rối.

+11

chỉ [ 'Collections.shuffle()'] (http://docs.oracle.com/javase/8/docs/api/java/util/Collections .html # shuffle-java.util.List-) danh sách và phát các bài hát từng người một trong vòng lặp for-each –

+0

Có bắt buộc phải gọi stopMP3 trước khi vòng lặp do-while kết thúc không? Tôi nghi ngờ một nguyên nhân có thể gây ra ngừng sớm ở đó. –

+0

Bạn có nhận được bất kỳ ngoại lệ nào không? –

Trả lời

7

Tôi nghĩ rằng vấn đề duy nhất nằm trong logic mà bạn đang sử dụng để xáo trộn danh sách.

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; 
} 

Khi số ngẫu nhiên được tạo đã tồn tại trong danh sách bài hátNếu bạn đang tạo một số ngẫu nhiên mới. Số ngẫu nhiên mới này không được chọn với tất cả các số của danh sách bài hát. Sự thay đổi sau đây sẽ giải quyết vấn đề của bạn.

boolean done = false; 
    while(!done){ 
     number = r.nextInt(song.size()); 
     if(!songNum.contains(number)) done = true; 
    } 

Ngoài ra, bạn có thể sử dụng gợi ý Sasha 's trong các ý kiến ​​cho xáo trộn danh sách (Collections.shuffle()).

3

Sự cố thực tế với thuật toán hiện tại của bạn là bạn không đặt lại counter khi phát hiện một bài hát đã được phát. Vì vậy, ngay sau khi bạn nhấn lặp lại, bạn bị kẹt trong một vòng lặp vô hạn - done sẽ không bao giờ đúng.

(Trên thực tế, nó sẽ không là vô hạn - một lần counter đạt Integer.MAX_VALUE nó sẽ quấn xung quanh để Integer.MIN_VALUE và cuối cùng đạt 0 một lần nữa, vì vậy nếu bạn còn lại nó đủ lâu nó cuối cùng sẽ chơi một bài hát)

Có một số gợi ý hữu ích ở đây đã về cải tiến mã và tôi sẽ không lặp lại chúng ở đây, nhưng sự thay đổi tối thiểu mà sẽ sửa chữa những gì bạn có là để di chuyển khởi của counter để 0 bên trong vòng lặp:

boolean done = false; 

while(!done){ 
    int counter = 0; // reset counter every time 

    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; 
} 
3

Sasha đã nói trong phần bình luận: sử dụng Collections.shuffle().Trên thực tế rằng sẽ trông một lil' một cái gì đó như thế này:

trong lớp Âm nhạc có một phương pháp để có được tất cả các bài hát:

public List<String> getSongs() {return music;} 

Vòng lặp trong MusicDriver sẽ là dọc theo dòng:

List<String> songs = song.getSongs(); 
do{ 
    Collections.shuffle(songs); 
    for (String songToPly: songs) { 
     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"); 
     mp3.stopMP3(); 
     line = s.nextLine(); 
     if (!line.equals("n")) break; 
    } 
}while(line.equals("n")); 

Trên ghi chú đặt tên biến, đặt tên thể hiện của lớp Âm nhạc là "bài hát" (số ít) là loại khó hiểu. Có thể gọi nó là "âm nhạc" hoặc ít nhất là "bài hát".

0

gì tôi sẽ làm là:

public class MainClass() { 

    public static void main(String[] args) { 
     PlayerWrapper player = new PlayerWrapper(); 
    } 
} 

public class PlayerWrapper() { 
    private List<MP3> playlist; 
    private Scanner userInputReader; 
    private String currentUserInput; 

    public PlayerWrapper() { 
     userInputReader = new Scanner(System.in()); 
     System.out.println("Filepath to playlist?"); 
     String playlistFileName = userInputReader.nextLine(); 
     playlist = PlayListExtractor.extractPlaylist(playlistFileName); 
     start(); 
    } 

    public void start() { 
     playlistCopy = new ArrayList<MP3>(playlist); 
     shufflePlayList(playlistCopy); 
     Iterator<MP3> songIterator = playlistCopy.iterator(); 
     while (songIterator.hasNext()) { 
      MP3 song = songIterator.next(); 
      songIterator.remove(); 
      player = new Player(song.toStream()); 
      player.play(); 
      displayCurrentSongAndCommands(song); 
      currentUserInput = userInputReader.nextLine(); 
      if ("Stop".equals(currentUserInput)) { 
       player.close(); 
       break; 
      } else if ("n".equals(currentUserInput)) { 
       player.close(); 
       continue; 
      } 
     } 

     if("Stop".equals(currentUserInput)) { 
      System.out.println("Playlist stopped. Press q to quit or c to continue"); 
      currentUserInput = userInputReader.nextLine(); 
      if ("q".equals(currentUserInput)) { 
       System.exit(0); 
      } else if ("c".equals(currentUserInput)) { 
       start(); 
      } 
     } 
     start(); 
    } 

    private void shufflePlayList(final List<MP3> playlistToBeShuffled) { 
     long seed = System.nanoTime(); 
     Collections.shuffle(playlistToBeShuffled, new Random(seed));    
    } 

    private void displayCurrentSongAndCommands(final MP3 currentSong) { 
     System.out.println("Now Playing " + currentSong.toString()); 
     System.out.println("Enter \"Stop\" to stop playing the song"); 
     System.out.println("Enter \"n\" to play the next song"); 
    } 
} 

public static class PlayListExtractor() { 
    private PlayListExtractor(); 

    public static List<MP3> extractPlayList(final String playListFileName) { 
     List<MP3> result = new ArrayList<>(); 
     try (BufferedReader br = new BufferedReader(new FileReader(file))) { 
      String line; 
      while ((line = br.readLine()) != null) { 
       result.add(new MP3(line)); 
      } 
      return result; 
     } catch (IOException e) { 
      System.out.println("Problem parsing playlist"); 
     } 
    } 
} 

public class MP3 { 
    private String filename; 

    public MP3(final String filename) { 
     this.filename = filename; 
    } 

    public BufferedInputStream toStream() { 
     try { 
      FileInputStream fis = new FileInputStream(filename); 
      return new BufferedInputStream(fis);     
     } 
     catch (Exception e) { 
      System.out.println("Problem playing file " + filename); 
      System.out.println(e); 
     } 
    } 

    public String toString() { 
     return filename; 
    } 
} 
Các vấn đề liên quan