# 綜合案例:播放器
[TOC]
## 導學
對于Java的學習,已經進入尾聲了。接下來,我們就通過一個綜合案例,來體驗一下在企業中如何進行項目的開發。本節課程,我們會按照項目需求分析、接口設計、環境搭建、功能模塊開發等階段入手,完成整個項目,并達到上線交付的成果。

## 需求分析
案例:播放器管理
* 任務:通過控制臺實現播放列表管理和播放器管理
* 具體需求:
1. 播放列表管理主要功能
* 將歌曲添加到主播放列表
* 將歌曲添加到普通播列表
* 通過歌曲id查詢到播放列表中的歌曲
* 通過歌曲名稱查詢播放列表中的歌曲
* 修改播放列表中的歌曲
* 刪除播放列表中的歌曲
* 顯示播放列表的所有歌曲
2. 播放器管理
* 向播放器添加播放列表
* 從播放器刪除播放列表
* 通過名字查詢播放列表信息
* 顯示所有列表名稱
* 詳細設計:
* 歌曲類(Song)

* 播放列表類(PlayList)



* 播放器類(PlayListCollection)


* 測試類(TestDemo)
對功能模塊進行調用測試,并在主方法中進行調用
## 歌曲類
~~~java
package com.dodoke.player.bean;
/**
* 歌曲類(實體類-功能僅僅是提供對一個類的描述)
* @author Dodoke
*
*/
public class Song implements Comparable<Song>{
private String id;//歌曲編號
private String name;
private String singer;//演唱者
public Song(String id, String name, String singer) {
super();
this.id = id;
this.name = name;
this.singer = singer;
}
public Song() {
super();
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSinger() {
return singer;
}
public void setSinger(String singer) {
this.singer = singer;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((singer == null) ? 0 : singer.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
//判斷對象是否相等,相等則返回true
if(this == obj) {
return true;
}
//this != true
if(obj.getClass() == Song.class) {
//類型相同才去進行比較
Song song = (Song)obj;
return (song.getId().equals(this.id)) && (song.getName().equals(this.name)) && (song.getSinger().equals(this.singer));
}
return false;
}
@Override
public String toString() {
return "歌曲信息:id為" + id + ", 歌曲名稱為" + name + ", 演唱者為" + singer;
}
@Override
public int compareTo(Song o) {
String name1 = o.getName();
int n = this.name.compareTo(name1);
return n;
}
}
~~~
## 播放列表類
~~~java
package com.dodoke.player.dao;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.dodoke.player.bean.Song;
/**
* 播放列表類(描述和數據操作相關的方法)
* @author Dodoke
*
*/
public class PlayList {
/**
* 播放列表名稱
*/
private String playListName;
/**
* 播放列表的歌曲集合
*/
private List<Song> musicList;
/**
* 在創建播放列表的時候,必須對播放列表命名
* @param playListName 播放列表名稱
*/
public PlayList(String playListName) {
super();
this.playListName = playListName;
musicList = new ArrayList<Song>();
}
/**
* 將歌曲添加到播放列表
* @param song 要添加的歌曲
*/
public void addToPlayList(Song song) {
//要排除重復添加的情況
boolean flag = false;
//判斷播放列表中歌曲是否存在
for(Song song1 : musicList) {
if(song1.equals(song)) {
flag = true;
break;
}
}
if(flag) {
System.out.println("該歌曲已經存在于播放列表中,添加失敗!");
} else {
//將歌曲添加到播放列表中
musicList.add(song);
}
}
/**
* 顯示播放列表中所有的歌曲
*/
public void displayAllSong() {
System.out.println("播放列表中所有歌曲為:");
for(Song song1 : musicList) {
System.out.println(song1);
}
}
/**
* 通過歌曲編號查詢播放列表中的歌曲
* @param id 歌曲編號
* @return 查詢到的的歌曲信息
*/
public Song searchSongById(String id) {
Song song = null;
//歌曲編號id唯一
for(Song song1 : musicList) {
String id1 = song1.getId();
if(id1.equals(id)) {
//編號相同,則歌曲就是相同的
song = song1;
break;
}
}
return song;
}
/**
* 根據歌曲名稱查詢歌曲
* @param name 歌曲名稱
* @return 查詢的歌曲信息
*/
public Song searchSongByName(String name) {
Song song = null;
for(Song song1 : musicList) {
String name1 = song1.getName();
if(name1.equals(name)) {
//編號相同,則歌曲就是相同的
song = song1;
break;
}
}
return song;
}
/**
* 修改播放列表中的歌曲信息
* @param id 要修改的歌曲id
* @param song 新的歌曲信息
*/
public void updateSong(String id, Song song) {
Song song1 = searchSongById(id);
if(song1 == null) {
System.out.println("沒有找到歌曲編號為" + id + "的歌曲信息!");
} else {
//先移除原有的歌曲信息,再對播放列表中的歌曲信息進行重新添加
musicList.remove(song1);
musicList.add(song);
System.out.println("修改成功!");
}
}
/**
* 刪除播放列表中指定的歌曲信息
* @param id 歌曲編號
*/
public void deleteSong(String id) {
Song song = searchSongById(id);
if(song == null) {
System.out.println("沒有找到歌曲編號為" + id + "的歌曲信息!");
} else {
musicList.remove(song);
System.out.println("刪除成功!");
}
}
/**
* 對歌曲名進行排序
*/
public void sortBySongName() {
Collections.sort(musicList);
}
public String getPlayListName() {
return playListName;
}
public void setPlayListName(String playListName) {
this.playListName = playListName;
}
public List<Song> getMusicList() {
return musicList;
}
public void setMusicList(List<Song> musicList) {
this.musicList = musicList;
}
}
~~~
## 播放器類
~~~java
package com.dodoke.player.dao;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* 設置該播放器為系統唯一播放器
* @author Dodoke
*
*/
public class Player {
private static Player palyer = new Player();
public static Player getInstance() {
return palyer;
}
Map<String, PlayList> map = new HashMap<String, PlayList>();;//存放播放列表的集合 key-播放列表名稱 value-播放列表
private Player() {
}
/**
* 向播放器中新增播放列表
* @param pl 要添加的播放列表
*/
public void addPlayList(PlayList pl) {
map.put(pl.getPlayListName(), pl);
}
/**
* 刪除播放列表
* @param pl 要刪除的播放列表
*/
public void deletePlayList(PlayList pl) {
map.remove(pl.getPlayListName());
System.out.println("刪除成功!");
}
/**
* 根據播放列表名稱查詢播放列表
* @param playListName 播放列表名稱
* @return 播放列表
*/
public PlayList searchPlayListByName(String playListName) {
PlayList pl = null;
//找到map中所有key值得集合
Set<String> plKeySet = map.keySet();
for(String s : plKeySet) {
//當集合中的key與參數相同時,也就是找到了播放列表
if(s.equals(playListName)) {
pl = map.get(s);
}
}
return pl;
}
/**
* 顯示所有播放列表的名稱
*/
public void displayListName() {
Set<String> plKeySet = map.keySet();
System.out.println("播放列表名稱為:");
for(String s : plKeySet) {
System.out.println(s);
}
}
public Map<String, PlayList> getMap() {
return map;
}
public void setMap(Map<String, PlayList> map) {
this.map = map;
}
}
~~~
## 測試類
~~~java
package com.dodoke.player.test;
import com.dodoke.player.bean.Song;
import com.dodoke.player.dao.PlayList;
import com.dodoke.player.dao.Player;
public class Test {
public static void main(String[] args) {
Test test = new Test();
test.testPlayer();
}
/**
* 對歌曲類進行測試
*/
public void testSong() {
Song song1 = new Song("s001","兩只老虎","小太陽");
Song song2 = new Song("s002","小燕子","風車");
Song song3 = new Song("s003","茉莉花","彩虹");
Song song4 = new Song("s003","茉莉花","彩虹");
//測試toString()方法
System.out.println(song1);
//測試song1和song3是否相等,測試song3和song4是否相等
System.out.println("song1==song3:" + song1.equals(song3));
System.out.println("song3==song4:" + song3.equals(song4));
}
/**
* 對播放列表類進行測試
*/
public void testPlayList() {
Song song1 = new Song("s001","兩只老虎","小太陽");
Song song2 = new Song("s002","小燕子","風車");
Song song3 = new Song("s003","茉莉花","彩虹");
Song song4 = new Song("s003","茉莉花","彩虹");
PlayList pl = new PlayList("主播放列表");
pl.addToPlayList(song1);
pl.addToPlayList(song2);
pl.addToPlayList(song3);
pl.addToPlayList(song4);
//顯示播放列表內容
pl.displayAllSong();
//通過id查詢歌曲信息
Song song = pl.searchSongById("s003");
if(song == null) {
System.out.println("抱歉,沒查到");
} else {
System.out.println(song);
}
//通過歌曲名稱查詢
song = null;
song = pl.searchSongByName("兩只老虎");
if(song == null) {
System.out.println("抱歉,沒查到");
} else {
System.out.println(song);
}
//修改歌曲信息
Song songnew = new Song("s004","突然的自我","伍佰");
pl.updateSong("s001", songnew);
pl.displayAllSong();
//歌曲排序
pl.sortBySongName();
pl.displayAllSong();
//刪除歌曲信息
pl.deleteSong("s002");
pl.displayAllSong();
}
/**
* 對播放器類進行測試
*/
public void testPlayer() {
Song song1 = new Song("s001","兩只老虎","小太陽");
Song song2 = new Song("s002","小燕子","風車");
Song song3 = new Song("s003","茉莉花","彩虹");
//創建主播放列表
PlayList mainPlayList = new PlayList("主播放列表");
mainPlayList.addToPlayList(song1);
mainPlayList.addToPlayList(song2);
mainPlayList.addToPlayList(song3);
//定義一個新的播放列表
PlayList pl = new PlayList("流行音樂");
//從主播放列表中獲取流行音樂
pl.addToPlayList(mainPlayList.getMusicList().get(0));
pl.addToPlayList(mainPlayList.getMusicList().get(1));
//將兩個播放列表添加到播放器中
Player player = Player.getInstance();
player.addPlayList(mainPlayList);
player.addPlayList(pl);
//展示播放列表名字
player.displayListName();
//根據播放列表名稱查詢播放列表信息,并顯示所有歌曲
PlayList plst = player.searchPlayListByName("流行音樂");
plst.displayAllSong();
//刪除播放列表信息
System.out.println("刪除前:");
player.displayListName();
System.out.println("刪除后:");
player.deletePlayList(pl);
player.displayListName();
}
}
~~~
## 程序運行服務類
~~~java
package com.dodoke.player.service;
import java.util.Scanner;
import com.dodoke.player.bean.Song;
import com.dodoke.player.dao.PlayList;
import com.dodoke.player.dao.Player;
/**
* 描述程序運行邏輯
* @author Dodoke
*
*/
public class PlayerService {
/**
* 主菜單
*/
public void mainMenu() {
System.out.println("*****************************************************");
System.out.println(" **主菜單** ");
System.out.println(" 1--播放列表管理 ");
System.out.println(" 2--播放器管理 ");
System.out.println(" 0--退出 ");
System.out.println("*****************************************************");
}
/**
* 播放列表管理菜單
*/
public void playListMenu() {
System.out.println("*****************************************************");
System.out.println(" **播放列表管理菜單** ");
System.out.println(" 1--將歌曲添加到主播放列表 ");
System.out.println(" 2--將歌曲添加到普通播列表 ");
System.out.println(" 3--通過歌曲id查詢到播放列表中的歌曲 ");
System.out.println(" 4--通過歌曲名稱查詢播放列表中的歌曲 ");
System.out.println(" 5--修改播放列表中的歌曲 ");
System.out.println(" 6--刪除播放列表中的歌曲 ");
System.out.println(" 7--顯示播放列表的所有歌曲 ");
System.out.println(" 9--返回上一級菜單 ");
System.out.println("*****************************************************");
}
/**
* 播放器菜單
*/
public void playerMenu() {
System.out.println("*****************************************************");
System.out.println(" **播放器管理菜單** ");
System.out.println(" 1--向播放器添加播放列表 ");
System.out.println(" 2--從播放器刪除播放列表 ");
System.out.println(" 3--通過名字查詢播放列表信息 ");
System.out.println(" 4--顯示所有播放列表名稱 ");
System.out.println(" 9--返回上一級菜單 ");
System.out.println("*****************************************************");
}
/**
* 執行程序邏輯規劃
*/
public void player() {
PlayerService plService = new PlayerService();
Scanner sc = new Scanner(System.in);
int input = 0, input1 = 0, input2 = 0;
//創建唯一的播放列表容器(播放器)
Player player = Player.getInstance();
//創建一個播放器自帶的主播放列表
PlayList mPlayList = new PlayList("主播放列表");
//將主播放列表添加到播放器
player.addPlayList(mPlayList);
//預先設置一個普通播放列表的變量名
PlayList pList = null;
while(true) {
plService.mainMenu();
System.out.println("請輸入對應的數字進行操作:");
input = sc.nextInt();//不再進行異常的處理
if(input == 0) {
System.out.println("退出程序!");
break;
}
//針對用戶在主菜單輸入的數字進行判斷處理
switch(input) {
case 1: {
//播放列表管理
while(true) {
plService.playListMenu();
System.out.println("請輸入對應的數字進行播放列表管理操作:");
input1 = sc.nextInt();
if(input1 == 9) {
break;
}
switch(input1) {
case 1: {
System.out.println("將歌曲添加到主播放列表!");
System.out.println("請輸入要添加的歌曲數量:");
int count = sc.nextInt();
for(int i = 1; i <= count; i++) {
System.out.println("請輸入第" + i + "首歌曲");
System.out.println("請輸入歌曲id");
String id = sc.next();
System.out.println("請輸入歌曲名稱");
String name = sc.next();
System.out.println("請輸入歌曲演唱者");
String singer = sc.next();
Song song = new Song(id, name, singer);
mPlayList.addToPlayList(song);
}
System.out.println("歌曲添加完畢!");
break;
}
case 2: {
System.out.println("將歌曲添加到普通播放列表!");
System.out.println("請輸入要添加的播放列表名稱:");
String playListName = sc.next();
//判斷播放列表是否在播放器中存在
pList = player.searchPlayListByName(playListName);
if(pList == null) {
System.out.println("該播放列表不存在,請先將播放列表添加到播放器中!");
} else {
System.out.println("請輸入要添加的歌曲數量:");
int count = sc.nextInt();
for(int i = 1; i <= count; i++) {
System.out.println("請輸入第" + i + "首歌曲");
System.out.println("請輸入歌曲id");
//去主播放列表查詢歌曲
String id = sc.next();
Song songs = mPlayList.searchSongById(id);
if(songs == null) {
//如果不存在則讓用戶繼續填寫歌曲信息,并將歌曲同時添加到主播放列表和普通播放列表(普通播放列表是主播放列表的子集)
System.out.println("該歌曲在主播放列表不存在,繼續輸入歌曲的其他信息!");
System.out.println("請輸入歌曲名稱");
String name = sc.next();
System.out.println("請輸入歌曲演唱者");
String singer = sc.next();
Song song = new Song(id, name, singer);
pList.addToPlayList(song);
mPlayList.addToPlayList(song);
} else {
//如果存在主播放列表,則直接將歌曲信息添加到普通播放列表
pList.addToPlayList(songs);
System.out.println("主播放列表中已有該歌曲,已將其添加到名為:" + playListName + "的歌單中!");
}
}
System.out.println("歌曲添加完畢!");
}
break;
}
case 3: {
System.out.println("通過歌曲id查詢到播放列表中的歌曲");
System.out.println("請輸入要查詢的播放列表名稱:");
String playListName = sc.next();
//判斷播放列表是否在播放器中存在
pList = player.searchPlayListByName(playListName);
if(pList == null) {
System.out.println("該播放列表不存在,請先將播放列表添加到播放器中!");
} else {
System.out.println("請輸入要查詢的歌曲id:");
String id = sc.next();
Song song = pList.searchSongById(id);
if(song == null) {
System.out.println("該歌曲在播放列表" + playListName + "中不存在!");
} else {
System.out.println("歌曲信息為:");
System.out.println(song);
}
}
break;
}
case 4: {
System.out.println("通過歌曲名稱查詢播放列表中的歌曲");
break;
}
case 5: {
System.out.println("修改播放列表中的歌曲");
break;
}
case 6: {
System.out.println("刪除播放列表中的歌曲");
break;
}
case 7: {
System.out.println("顯示播放列表的所有歌曲");
System.out.println("請輸入要查詢的播放列表");
String playListName = sc.next();
PlayList plst = player.searchPlayListByName(playListName);
if(plst == null) {
System.out.println("抱歉,您輸入的列表名稱沒有匹配!");
} else {
plst.displayAllSong();
}
break;
}
default: {
System.out.println("該數字沒有對應的操作");
break;
}
}
}
break;//對于死循環明確終止以后,才可以寫,否則認為是無用代碼
}
case 2: {
//播放器管理
while(true) {
plService.playerMenu();
System.out.println("請輸入對應的數字進行播放器管理操作:");
input2 = sc.nextInt();
if(input2 == 9) {
break;
}
switch(input2) {
case 1: {
System.out.println("向播放器添加播放列表!");
System.out.println("請輸入要添加的播放列表名稱");
String playName = sc.next();
if(playName.equals("主播放列表")) {
System.out.println("主播放列表無需創建!");
} else {
pList = new PlayList(playName);
//將創建好的播放列表對象添加到播放器中
player.addPlayList(pList);
System.out.println("播放列表創建完畢!");
}
break;
}
case 2: {
System.out.println("從播放器刪除播放列表!");
System.out.println("請輸入要刪除的播放列表名稱:");
String playListName = sc.next();
if(playListName.equals("主播放列表")) {
System.out.println("抱歉!主播放列表不能刪除!");
break;
}
//查詢要刪除的播放列表是否存在
PlayList pList1 = player.searchPlayListByName(playListName);
if(pList1 == null) {
System.out.println("該播放列表不存在!");
} else {
player.deletePlayList(pList1);
}
break;
}
case 3: {
System.out.println("通過名字查詢播放列表信息!");
System.out.println("請輸入要查詢的播放列表名稱:");
String playListName = sc.next();
PlayList pList2 = player.searchPlayListByName(playListName);
if(pList2 == null) {
System.out.println("該播放列表不存在!");
} else {
System.out.println("已查詢到該播放列表");
System.out.println("該播放列表名稱為:" + playListName);
pList2.displayAllSong();
}
break;
}
case 4: {
System.out.println("顯示所有列表名稱!");
player.displayListName();
break;
}
default: {
System.out.println("該數字沒有對應的操作");
break;
}
}
}
break;
}
default: {
System.out.println("該數字沒有對應的操作");
}
}
}
}
}
~~~
## 控制類
~~~java
package com.dodoke.player.controller;
import com.dodoke.player.service.PlayerService;
/**
* 控制層-調用程序運行邏輯
* @author Dodoke
*
*/
public class PlayerController {
public static void main(String[] args) {
PlayerService play = new PlayerService();
play.player();
}
}
~~~