0

Im trying to iterate a Linked List inside of a linked list but I'm not sure how to proceed with it. I'm used to using a passed parameter for what will be iterated but when I'm iterating a linked list within a linked list I won't know the list that will have a match for the element that I'm comparing to.

currently, the iterator for the inner linkedlist "nestedLinkedListIterator" is preventing compile because "nestedAlbum" does not have a corresponding parameter. I didn't provide a parameter because the inner LinkedList "nestedLinkedListIterator" could potentially be changing as the outer Linked list is iterated through while being checked with the passed title parameter into the dummy object.

Here is an example of what I’m trying to do

private static boolean addSongFromAlbumToAlbum(LinkedList<Album> albums1, LinkedList<Song> targetAlbum,
 String title){
 //creating a dummy song for comparison using title parameter with arbitrary time duration.
 Song dummySong = new Song(title, 000);
 ListIterator<Album> albumsListIterator = albums1.listIterator();
 ListIterator<Song> targetAlbumListIterator = targetAlbum.listIterator();
 //nested LinkedList iterator (for the song LinkedList is each album being iterated.
 ListIterator<Song> nestedLinkedListIterator = nestedAlbum.listIterator();
 /*if the "nestedAlbum" is going to change with every iteration of the outer Linked list how can I
 * use the nestedAlbum.listIterator with it. normaly I am used to using a parameter tha is passed in
 * the place of "nestedAlbum" but I don't think that would work because wither every new album element in "albums1"
 * there will be a new song list. correct me if im wrong*/
 //checking whether the song with the "title" parameter entered exists in the LinkedList
 //of albums
 while(albumsListIterator.hasNext()){
 while(nestedLinkedListIterator.hasNext()){
 //checking if current iteration has an object with same value for title as title parameter.
 Song comparisonSongToAdd = nestedLinkedListIterator.next();
 int comparisonValue = comparisonSongToAdd.getTitle().compareTo(title);
 if(comparisonValue ==0){
 //check whether the found object already exists in the album
 while (targetAlbumListIterator.hasNext()){
 SongComparator comparator = new SongComparator(); //create new comparator object to compare
 int comparatorValue = comparator.compare(comparisonSongToAdd, targetAlbumListIterator.next());
 if (comparatorValue == 0) {
 System.out.println(comparisonSongToAdd + " already exists in the Album. please choose\n a different song.");
 return false;
 }//end if comparator
 }//end target album while
 targetAlbumListIterator.add(comparisonSongToAdd);
 }//end if song title found
 }//end nested album while
 }//end albums while iterator
 return true;
 }//end addSongFromAlbum method

///SongComparator class

import java.util.Comparator;
public class SongComparator implements Comparator<Song> {
 public int compare(Song song1, Song song2){
 if(song1.getTitle() == song2.getTitle() && song1.getDurationSeconds() == song2.getDurationSeconds()){
 return 0;
 }else{
 return -1;
 }
 }
}
asked Jul 30, 2020 at 20:23
2
  • 1
    Based on some gleaned ideas from your code, I don't think that using two discreet lists is correct. I think the list of Albums needs to be a list of lists: LinkedList<List<Songs>> albums Commented Jul 30, 2020 at 20:27
  • 1
    Your comparator is not valid because it never returns the value 1. Commented Jul 30, 2020 at 20:38

1 Answer 1

1

I did not fully understand what you were trying to achieve with your code, but I will try to answer your question starting from @markspace's observation.

So I will be assuming that you are trying to iterate through a list of albums: albums1 and save all the songs which match the given title in the targetAlbum variable.

There are multiple points that can be improved in your code:

  • the variable dummySong is redundant
  • using iterators makes the code harder to read, try going for for loops
  • a comparator cannot be used to naturally order songs (2 songs with different titles cannot be compared), so it's best to go for using the equals() method

This is a method that should cover what you asked for in your post:


private static boolean addSongFromAlbumToAlbum(LinkedList<LinkedList<Song>> albums, LinkedList<Song> targetAlbum, String title) {
 ListIterator<LinkedList<Song>> albumsListIterator = albums.listIterator();
 ListIterator<Song> targetAlbumListIterator = targetAlbum.listIterator();
 ListIterator<Song> albumSongListIterator;
 while(albumsListIterator.hasNext()) {
 
 LinkedList<Song> currentAlbumSongs = albumsListIterator.next();
 albumSongListIterator = currentAlbumSongs.listIterator();
 while(albumSongListIterator.hasNext()) {
 Song comparisonSongToAdd = albumSongListIterator.next();
 boolean songMatchFound = comparisonSongToAdd.getTitle().equals(title);
 
 if(songMatchFound){
 while (targetAlbumListIterator.hasNext()) {
 
 Song currentTargetAlbumSong = targetAlbumListIterator.next();
 
 if (currentTargetAlbumSong.equals(comparisonSongToAdd)) {
 System.out.println(comparisonSongToAdd + " already exists in the Album. please choose\n a different song.");
 return false;
 }
 }
 targetAlbumListIterator.add(comparisonSongToAdd);
 }
 }
 }
 return true;
}

Below is a demo program that covers:

  • a main function to test the program
  • my interpretation of Album and Song
  • an equals method on the Song class
  • a refactored method covering my points above

public class HelloWorld {
 public static void main(String []args) {
 
 LinkedList<Song> greenDayAlbum = new LinkedList<>();
 
 greenDayAlbum.add(new Song("21 Guns", 3));
 greenDayAlbum.add(new Song("Basket Case", 3));
 greenDayAlbum.add(new Song("American Idiot", 3));
 
 LinkedList<Song> linkinParkAlbum = new LinkedList<>();
 
 linkinParkAlbum.add(new Song("Numb", 3));
 linkinParkAlbum.add(new Song("In the end", 3));
 linkinParkAlbum.add(new Song("Castle of glass", 3));
 
 LinkedList<LinkedList<Song>> albums = new LinkedList<>();
 albums.add(greenDayAlbum);
 albums.add(linkinParkAlbum);
 
 LinkedList<Song> targetAlbum = new LinkedList<>();
 
 //addSongFromAlbumToAlbum(albums, targetAlbum, "Basket Case");
 findMatchedSongs(albums, targetAlbum, "Basket Case");
 
 for(Song matchedSong : targetAlbum) {
 System.out.println(matchedSong); //outputs Song[title=Basket Case, duration=3]
 }
 }
 
 private static boolean findMatchedSongs(LinkedList<LinkedList<Song>> inputAlbums, LinkedList<Song> outputAlbum, String searchedTitle) {
 
 if (searchedTitle == null) {
 System.out.println("Provide a title to search for.");
 return false;
 }
 
 for (LinkedList<Song> songs : inputAlbums) {
 for (Song song : songs) {
 if (!searchedTitle.equals(song.getTitle())) {
 continue;
 }
 if (outputAlbum.contains(song)) {
 System.out.println(String.format("Song %s already exists in the album; please choose a different song", song.getTitle()));
 return false;
 }
 
 outputAlbum.add(song);
 }
 }
 return true;
 }
}
class Album {
 
 private Collection<Song> songs;
 
 public Album(Collection<Song> songs) {
 this.songs = songs;
 }
 
}
class Song {
 
 String title;
 int duration;
 
 Song(String a, int b) {
 this.title = a;
 this. duration = b;
 }
 
 public String getTitle() {
 return title;
 }
 
 public int getDurationSeconds() {
 return duration;
 }
 
 @Override
 public boolean equals(Object that) {
 
 if (that == null) {
 return false;
 }
 
 if (!(that instanceof Song)) {
 return false;
 }
 
 Song song = (Song) that;
 
 if (this.title != null && !this.title.equals(song.getTitle())) {
 return false;
 }
 
 if (this.duration != song.getDurationSeconds()) {
 return false;
 }
 
 return true;
 }
 //hashCode() function omitted for brevity
 
 @Override
 public String toString() {
 return String.format("Song[title=%s, duration=%d]", title, duration);
 }
 
}
answered Jul 30, 2020 at 22:29
1
  • 1
    Thanks that is exactly what I was trying to do. sorry for the miscomunitcation. Ill give this a shot and let you know Commented Jul 31, 2020 at 1:13

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.