我试图在链表中迭代链表,但我不知道如何进行。我习惯于使用传递的参数来迭代什么,但当我在链表中遍历链表时,我不知道与我要比较的元素匹配的列表。
当前,内部链表的迭代器";nestedLinkedListIterator";正在阻止编译,因为";nestedAlbum"没有相应的参数。我没有提供参数,因为内部LinkedList";nestedLinkedListIterator";在使用传递的title参数检查伪对象时,外部链表可能会发生变化。
下面是我尝试做的一个例子
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 choosen 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类
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;
}
}
}
我不完全理解您试图用代码实现什么,但我将从@markspace的观察开始回答您的问题。
因此,我假设您正在尝试遍历专辑列表:albums1
,并将所有与给定title
匹配的歌曲保存在targetAlbum
变量中。
在你的代码中有多个可以改进的地方:
- 变量
dummySong
是多余的 - 使用迭代器会使代码更难阅读,请尝试使用
for
循环 - 比较器不能用于自然排序歌曲(不能比较两首不同标题的歌曲(,因此最好使用equals((方法
这是一种方法,应该涵盖你在帖子中要求的内容:
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 choosen a different song.");
return false;
}
}
targetAlbumListIterator.add(comparisonSongToAdd);
}
}
}
return true;
}
下面是一个演示程序,涵盖:
- 测试程序的主要函数
- 我对专辑与歌曲的解读
- Song类上的equals方法
- 一个涵盖我以上观点的重构方法
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);
}
}