CC-19 : Simulate a Song Playlist using CircularDoubleLinkedList.
Description:
Write and test code to simulate a Songs playlist. The Playlist should initially have 5 songs. User can add a song at the end of the playlist. User can also move to next or previous song in the play list.
Test cases and expected outputs:
| Input Parameters |
Expected outputs |
Music Playlist Simulation menu :
1: Add a new song to playlist
2: Move to next song in playlist
3: Move to previous song in playlist
4: Show current music playlist
5: Exit Music Playlist Simulation program
Choose an option:
1
|
Current Music Playlist: Song1 (last node points to first node)
|
Choose an option:
1
|
Current Music Playlist: Song1 <-> Song2 (last node points to first node)
|
Choose an option:
1
|
Current Music Playlist: Song1 <-> Song2 <-> Song3 (last node points to first node)
|
Choose an option:
2
|
Current Music Playlist: Song1(Current Song) <-> Song2 <-> Song3 (last node points to first node)
|
Choose an option:
2
|
Current Music Playlist: Song1 <-> Song2(Current Song) <-> Song3 (last node points to first node)
|
Choose an option:
2
|
Current Music Playlist: Song1 <-> Song2 <-> Song3(Current Song) (last node points to first node)
|
Choose an option:
3
|
Current Music Playlist: Song1 <-> Song2(Current Song) <-> Song3 (last node points to first node)
|
Pseudocode:
| Create a CircularDoubleLinkedListNode class with String Data (instead of integer data that was used in above examples, song names are stored as node data values).
|
| Initialize a CircularDoubleLinkedList with list of 5 songs initially.
|
| To allow user to add a new Song node into playlist use CircularDoubleLinkedList “addNode()” method.
|
| To give user Option to delete current Song node from playlist, use CircularDoubleLinkedList method “removeNode()”.
|
| Use CircularDoubleLinkedListNode methods “getNextNode()” and “getPreviousNode()” to go to previous or next nodes.
|
Code:
public void circularDoubleLinkedListMusicPlaylist() throws Exception{
DoubleLinkedListNode currentSongInPlaylist=null;
int newSongCounter=0;
while (true) {
try {
System.out.println("\n\n Music Playlist Simulation menu :");
System.out.println();
System.out.println("1: Add a new song to playlist");
System.out.println("2: Move to next song in playlist");
System.out.println("3: Move to previous song in playlist");
System.out.println("4: Show current music playlist");
System.out.println("5: Exit Music Playlist Simulation program");
System.out.println();
System.out.println("Choose an option:\n");
int selectedMenuOption=readIntegerFromConsole();
switch(selectedMenuOption) {
case 1://Add a new song
newSongCounter++;
// Handle case of new song being first or last song in the Music Playlist
musicPlaylist.addLast(newSongCounter);
printMusicPlaylist(musicPlaylist,currentSongInPlaylist);
break;
case 2: //Play next song in playlist
if (musicPlaylist.getFirstNode()==null)
{System.out.print("\n\n Cannot move to next song; playlist is empty \n");
continue;}
if (currentSongInPlaylist==null) {
currentSongInPlaylist=musicPlaylist.getFirstNode();
printMusicPlaylist(musicPlaylist,currentSongInPlaylist);
continue;
}else {
currentSongInPlaylist=currentSongInPlaylist.getNextNode();
printMusicPlaylist(musicPlaylist,currentSongInPlaylist);
}
break;
case 3: //Move To previous song in playlist
if (musicPlaylist.getFirstNode()==null) {
System.out.print("\n\n Cannot move to previoius song; playlist is empty \n");
continue;}
if (currentSongInPlaylist==null) {
currentSongInPlaylist=musicPlaylist.getFirstNode();
printMusicPlaylist(musicPlaylist,currentSongInPlaylist);
continue;
}else {
currentSongInPlaylist=currentSongInPlaylist.getPreviousNode();
printMusicPlaylist(musicPlaylist,currentSongInPlaylist);
}
break;
case 4: //Show current music playlist
printMusicPlaylist(musicPlaylist,currentSongInPlaylist);
break;
case 5: //Exit the program
System.out.println("\nExiting program....\n");
return;
default: //user has input an option that is not available
System.out.print("\n Invalid option selected; please use one of the options given above: ");
break;}
}catch (Exception exception) {
System.out.print("Exception: "+ exception);
continue;
}
}
}
}
Click here to download and run code and test cases !
Below fully running code can be copied and run on Eclipse or other Java IDEs. Refer the classname in code below. If the class name below is "A", save the code below to a file named A.java before running it.
Be sure to try your own test cases to enhance your understanding !
You can also tweak the code to optimize or add enhancements and custom features.
Note: For easier code execution and easier reference, the class below contains code for CircularDoubleLinkedList and DoubleLinkedListNode as internal classes. Ideally both these classes should be separate public classes.
import java.util.Scanner;
public class CircularDoubleLinkedListMusicPlaylist {
CircularDoubleLinkedList musicPlaylist=this.new CircularDoubleLinkedList();
public void circularDoubleLinkedListMusicPlaylist() throws Exception{
DoubleLinkedListNode currentSongInPlaylist=null;
int newSongCounter=0;
while (true) {
try {
System.out.println("\n\n Music Playlist Simulation menu :");
System.out.println();
System.out.println("1: Add a new song to playlist");
System.out.println("2: Move to next song in playlist");
System.out.println("3: Move to previous song in playlist");
System.out.println("4: Show current music playlist");
System.out.println("5: Exit Music Playlist Simulation program");
System.out.println();
System.out.println("Choose an option:\n");
int selectedMenuOption=readIntegerFromConsole();
switch(selectedMenuOption) {
case 1://Add a new song
newSongCounter++;
// Handle case of new song being first or last song in the Music Playlist
musicPlaylist.addLast(newSongCounter);
printMusicPlaylist(musicPlaylist,currentSongInPlaylist);
break;
case 2: //Play next song in playlist
if (musicPlaylist.getFirstNode()==null)
{System.out.print("\n\n Cannot move to next song; playlist is empty \n");
continue;}
if (currentSongInPlaylist==null) {
currentSongInPlaylist=musicPlaylist.getFirstNode();
printMusicPlaylist(musicPlaylist,currentSongInPlaylist);
continue;
}else {
currentSongInPlaylist=currentSongInPlaylist.getNextNode();
printMusicPlaylist(musicPlaylist,currentSongInPlaylist);
}
break;
case 3: //Move To previous song in playlist
if (musicPlaylist.getFirstNode()==null) {
System.out.print("\n\n Cannot move to previoius song; playlist is empty \n");
continue;}
if (currentSongInPlaylist==null) {
currentSongInPlaylist=musicPlaylist.getFirstNode();
printMusicPlaylist(musicPlaylist,currentSongInPlaylist);
continue;
}else {
currentSongInPlaylist=currentSongInPlaylist.getPreviousNode();
printMusicPlaylist(musicPlaylist,currentSongInPlaylist);
}
break;
case 4: //Show current music playlist
printMusicPlaylist(musicPlaylist,currentSongInPlaylist);
break;
case 5: //Exit the program
System.out.println("\nExiting program....\n");
return;
default: //user has input an option that is not available
System.out.print("\n Invalid option selected; please use one of the options given above: ");
break;}
}catch (Exception exception) {
System.out.print("Exception: "+ exception);
continue;
}
}
}
public static void printMusicPlaylist(CircularDoubleLinkedList musicPlaylist, DoubleLinkedListNode currentSongInMusicPlaylist) throws Exception {
DoubleLinkedListNode firstNode=musicPlaylist.getFirstNode();
if (firstNode == null) {
System.out.println("\n\n Music Playlist empty\n"); return; }
DoubleLinkedListNode currentNode=musicPlaylist.getFirstNode();
System.out.println();
System.out.println("*************************");
System.out.print("Current Music Playlist: ");
do {
System.out.print("Song"+currentNode.getNodeData());
if (currentNode==currentSongInMusicPlaylist) {System.out.print("(Current Song)");}
if (currentNode.getNextNode()!=firstNode) { System.out.print(" <-> "); }
currentNode=currentNode.getNextNode();
} while( currentNode != firstNode);
System.out.print(" ");
System.out.println();
System.out.println("**********************");
System.out.println();
Thread.sleep(2000);
return;
}
public static void main(String[] args) {
try {
CircularDoubleLinkedListMusicPlaylist circularDoubleLinkedListMusicPlaylist=new
CircularDoubleLinkedListMusicPlaylist();
circularDoubleLinkedListMusicPlaylist.circularDoubleLinkedListMusicPlaylist();
}catch (Exception exception) {
System.out.print("Exception: "+ exception);
}
}
class CircularDoubleLinkedList {
private DoubleLinkedListNode firstNode=null;
public DoubleLinkedListNode getFirstNode() {
return firstNode;
}
public void setFirstNode(DoubleLinkedListNode firstNode) {
this.firstNode = firstNode;
}
public DoubleLinkedListNode getLastNode() {
if (firstNode==null) {return null;}
DoubleLinkedListNode currentNode=firstNode;
DoubleLinkedListNode prevNode=null;
do {
prevNode=currentNode;
currentNode=currentNode.getNextNode();
}while (currentNode !=firstNode);
return prevNode;
}
public boolean addLast(int data){
DoubleLinkedListNode node=new DoubleLinkedListNode();
node.setNodeData(data);
if (firstNode==null) {
firstNode=node;
node.setNextNode(node);
node.setPreviousNode(node);
return true;
}
else {
DoubleLinkedListNode currentNode=firstNode;
while (currentNode.getNextNode()!=firstNode) {currentNode=currentNode.getNextNode();}
node.setPreviousNode(currentNode);
node.setNextNode(firstNode);
currentNode.setNextNode(node);
firstNode.setPreviousNode(node);
return true;
}
}
public boolean addFirst(int data){
DoubleLinkedListNode node=new DoubleLinkedListNode();
node.setNodeData(data);
if (firstNode==null) {
firstNode=node;
node.setNextNode(node);
node.setPreviousNode(node);
return true;
}else {
DoubleLinkedListNode currentNode=firstNode;
while (currentNode.getNextNode()!=firstNode) {currentNode=currentNode.getNextNode();}
node.setNextNode(firstNode);
node.setPreviousNode(currentNode);
firstNode.setPreviousNode(node);
firstNode=node;
currentNode.setNextNode(node);
return true;
}
}
public boolean add(int data, int pos){
int size=getSize();
if ((pos<0) || (pos > size)) { return false;}
if (pos==0) {
addFirst(data);
return true;
}
if (pos==size) {
addLast(data);
return true;
}
if (firstNode==null) { return false;}
DoubleLinkedListNode node=new DoubleLinkedListNode();
node.setNodeData(data);
DoubleLinkedListNode currentNode=firstNode;
DoubleLinkedListNode prevNode=null;
int idx=0;
while (currentNode !=null) {
if ((idx==pos)){
node.setNextNode(prevNode.getNextNode());
prevNode.setNextNode(node);
//setup previous node linkages
node.getNextNode().setPreviousNode(node);
node.setPreviousNode(prevNode);
return true;
}
prevNode=currentNode;
currentNode=currentNode.getNextNode();
idx++;
}
return false;
}
public int getSize() {
if (firstNode==null) { return 0;}
DoubleLinkedListNode currentNode=firstNode;
int idx=0;
do {
currentNode=currentNode.getNextNode();
idx++;
}while (currentNode !=firstNode);
return idx;
}
public boolean removeFirst() {
if (firstNode == null) { return false; }
if (firstNode.getNextNode()==firstNode) {
firstNode=null;
return true;
}
DoubleLinkedListNode currentNode=firstNode;
while (currentNode.getNextNode()!=firstNode) {currentNode=currentNode.getNextNode();}
firstNode=firstNode.getNextNode();
firstNode.setPreviousNode(currentNode);
currentNode.setNextNode(firstNode);
return true;
}
public boolean removeLast() {
if (firstNode == null) { return false; }
DoubleLinkedListNode currentNode=firstNode;
DoubleLinkedListNode prevNode=null;
do {
if (currentNode.getNextNode()==firstNode) {
if (prevNode==null) {
firstNode=null;
return true;
}
prevNode.setNextNode(firstNode);
firstNode.setPreviousNode(prevNode);
currentNode.setPreviousNode(firstNode);
return true;
}
prevNode=currentNode;
currentNode=currentNode.getNextNode();
} while (currentNode !=null);
return false;
}
public boolean remove(int data){
DoubleLinkedListNode currentNode=firstNode;
DoubleLinkedListNode prevNode=null;
do {
if (currentNode.getNodeData() == data) {
if (prevNode==null) {
removeFirst();
return true;
}
if (currentNode.getNextNode()==firstNode) {
removeLast();
return true;
}
prevNode.setNextNode(currentNode.getNextNode());
prevNode.getNextNode().setPreviousNode(prevNode);
return true;
}
prevNode=currentNode;
currentNode=currentNode.getNextNode();
} while (currentNode !=firstNode);
return false;
}
public boolean removeAtPos(int pos){
if (firstNode == null) { return false; }
DoubleLinkedListNode currentNode=firstNode;
DoubleLinkedListNode prevNode=null;
int idx=0;
do {
if (idx==pos) {
if (prevNode==null) {
removeFirst();
return true;
}
if (currentNode.getNextNode()==null) {
removeLast();
return true;
}
prevNode.setNextNode(currentNode.getNextNode());
return true;
}
prevNode=currentNode;
currentNode=currentNode.getNextNode();
idx++;
} while (currentNode !=firstNode);
return false;
}
public int get(int idx) {
if (firstNode == null) { return Integer.MIN_VALUE; }
DoubleLinkedListNode currentNode=firstNode;
int currIdx=0;
do {
if (currIdx==idx) {return currentNode.getNodeData();}
currentNode=currentNode.getNextNode();
currIdx++;
} while (currentNode !=firstNode);
return Integer.MIN_VALUE;
}
public void traverseForward() {
DoubleLinkedListNode currentNode=firstNode;
do {
System.out.println(currentNode.getNodeData());
currentNode=currentNode.getNextNode();
}while (currentNode !=firstNode);
}
// print CircularDoubleLinkList forward direction
public void printDoubleLinkListForwardDirection() throws Exception {
// Case 1: The Linked list is empty !!
if (firstNode == null) { System.out.println("CircularDoubleLinkedlist empty"); return; }
// Case 2: Print Circular Double LinkedList node by node (first to last)
DoubleLinkedListNode currentNode=firstNode;
System.out.println();
System.out.println("*************************************************");
System.out.print("Circular DoubleLinkedList nodes (first node to last node): ");
do {
System.out.print(currentNode.getNodeData());
if (currentNode.getNextNode()!=firstNode) System.out.print(" -> ");
currentNode=currentNode.getNextNode();
} while( currentNode != firstNode);
System.out.print("");
System.out.println();
System.out.println("*************************************************");
System.out.println();
Thread.sleep(2000);
return;
}
// print CircularDoubleLinkList backward direction
public void printDoubleLinkListBackwardDirection() throws Exception {
// Case 1: The Linked list is empty !!
if (firstNode == null) { System.out.println("Circular Double Linked list empty"); return; }
// Case 2: Print Circular Double LinkedList node by node (last to first)
// This while loop executes till we reach last node in the LinkedList
DoubleLinkedListNode currentNode=firstNode;
while (currentNode.getNextNode()!=firstNode) {currentNode=currentNode.getNextNode();}
//currentNode is at end of LinkedList
System.out.println();
System.out.println("*************************************************");
System.out.print("DoubleLinkedList nodes (last node to first node): ");
do {
System.out.print(currentNode.getNodeData());
if (currentNode != firstNode) System.out.print(" -> ");
currentNode=currentNode.getPreviousNode();
} while( currentNode != firstNode.getPreviousNode());
System.out.print("");
System.out.println();
System.out.println("*************************************************");
System.out.println();
Thread.sleep(2000);
return;
}
}
public int readIntegerFromConsole() throws Exception{
try {
Scanner in = new Scanner(System.in);
int intInput = in.nextInt();
return intInput;
} catch (Exception e){
System.out.println("Entered Option was not an integer");
throw new Exception();
}
}
class DoubleLinkedListNode {
private DoubleLinkedListNode nextNode=null;
private DoubleLinkedListNode previousNode=null;
private int nodeData=0;
public DoubleLinkedListNode getNextNode() {
return nextNode;
}
public void setNextNode(DoubleLinkedListNode nextNode) {
this.nextNode = nextNode;
}
public DoubleLinkedListNode getPreviousNode() {
return previousNode;
}
public void setPreviousNode(DoubleLinkedListNode previousNode) {
this.previousNode = previousNode;
}
public int getNodeData() {
return nodeData;
}
public void setNodeData(int nodeData) {
this.nodeData = nodeData;
}
}
}