迭代和检查链表中的链表元素

huangapple go评论59阅读模式
英文:

Iteration and checking element of an LinkedList of a LinkedList

问题

我试图在一个链表内部迭代另一个链表,但我不确定如何继续进行。我习惯于使用传递的参数来确定将要迭代的内容,但当我在链表内部迭代链表时,我不会知道将与我要比较的元素匹配的列表。

目前,内部链表的迭代器 "nestedLinkedListIterator" 无法通过编译,因为 "nestedAlbum" 没有相应的参数。我没有提供参数,因为内部链表 "nestedLinkedListIterator" 在外部链表迭代时可能会随着传递给虚拟对象的标题参数的检查而更改。

以下是我尝试做的示例:

private static boolean addSongFromAlbumToAlbum(LinkedList<Album> albums1, LinkedList<Song> targetAlbum,
                                                 String title){
    

    
            //使用标题参数创建一个用于比较的虚拟歌曲,具有任意的时长。
            Song dummySong = new Song(title, 000);
    
            ListIterator<Album> albumsListIterator = albums1.listIterator();
            ListIterator<Song> targetAlbumListIterator = targetAlbum.listIterator();
    
            //嵌套链表迭代器(用于迭代每个专辑的歌曲链表。
            ListIterator<Song> nestedLinkedListIterator = nestedAlbum.listIterator();
    
            /*如果"nestedAlbum"在外部链表的每次迭代中都会更改,那么我如何使用嵌套的nestedAlbum.listIterator呢?
            *通常情况下,我习惯于在"nestedAlbum"的位置使用传递的参数,但我认为这不会起作用,因为在"albums1"中的每个新专辑元素中都将有一个新的歌曲列表。请纠正我如果我错了*/
    
            //检查标题参数输入的歌曲是否存在于专辑的链表中
            while(albumsListIterator.hasNext()){
    
                while(nestedLinkedListIterator.hasNext()){
    
                    //检查当前迭代是否有与标题参数相同值的对象。
    
                    Song comparisonSongToAdd = nestedLinkedListIterator.next();
                    int comparisonValue = comparisonSongToAdd.getTitle().compareTo(title);
                    if(comparisonValue == 0){
    
                        //检查找到的对象是否已经存在于专辑中
                        while (targetAlbumListIterator.hasNext()){
                            SongComparator comparator = new SongComparator(); //创建新的比较器对象以进行比较
    
                            int comparatorValue = comparator.compare(comparisonSongToAdd, targetAlbumListIterator.next());
                            if (comparatorValue == 0) {
                                System.out.println(comparisonSongToAdd + "已经存在于专辑中,请选择\n不同的歌曲。");
                                return false;
    
                            }//结束比较器
    
                        }//结束目标专辑迭代器
                        targetAlbumListIterator.add(comparisonSongToAdd);
    
                    }//结束歌曲标题找到
    
                }//结束嵌套专辑迭代器
            }//结束专辑迭代器
            return true;
    
        }//结束addSongFromAlbum方法

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

注意:请确保在上述代码中定义和初始化 "nestedAlbum",以便在迭代过程中使用。此外,还需要确保 Song 类的定义和相关方法已正确定义和实现。

英文:

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&lt;Album&gt; albums1, LinkedList&lt;Song&gt; targetAlbum,
String title){
//creating a dummy song for comparison using title parameter with arbitrary time duration.
Song dummySong = new Song(title, 000);
ListIterator&lt;Album&gt; albumsListIterator = albums1.listIterator();
ListIterator&lt;Song&gt; targetAlbumListIterator = targetAlbum.listIterator();
//nested LinkedList iterator (for the song LinkedList is each album being iterated.
ListIterator&lt;Song&gt; nestedLinkedListIterator = nestedAlbum.listIterator();
/*if the &quot;nestedAlbum&quot; 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 &quot;nestedAlbum&quot; but I don&#39;t think that would work because wither every new album element in &quot;albums1&quot;
* there will be a new song list. correct me if im wrong*/
//checking whether the song with the &quot;title&quot; 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 + &quot; already exists in the Album. please choose\n a different song.&quot;);
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&lt;Song&gt; {
public int compare(Song song1, Song song2){
if(song1.getTitle() == song2.getTitle() &amp;&amp; song1.getDurationSeconds() == song2.getDurationSeconds()){
return 0;
}else{
return -1;
}
}
}

答案1

得分: 1

我将为您翻译代码部分:

我没有完全理解您在代码中尝试实现的目标但我将从 @markspace 的观察开始尝试回答您的问题

所以我会假设您正在尝试遍历一个包含专辑的列表:`albums1`,并将与给定的 `title` 匹配的所有歌曲保存在 `targetAlbum` 变量中

在您的代码中有多个可以改进的地方

* 变量 `dummySong` 是多余的
* 使用迭代器使代码更难阅读尝试使用 `for` 循环
* 不能使用比较器来自然排序歌曲具有不同标题的两首歌曲无法比较),最好使用 equals() 方法

这是一个应该涵盖您在帖子中提到的内容的方法

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

以下是一个演示程序,涵盖了以下内容:

  • 一个用于测试程序的主函数
  • 我对专辑和歌曲的理解
  • 歌曲类上的 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); //输出 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() 方法为简洁起见省略

    @Override
    public String toString() {
        return String.format("Song[title=%s, duration=%d]", title, duration);
    }
}

希望这可以帮助您理解代码的内容。如果您需要更多帮助,请随时提出问题。

英文:

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&lt;LinkedList&lt;Song&gt;&gt; albums, LinkedList&lt;Song&gt; targetAlbum, String title) {
ListIterator&lt;LinkedList&lt;Song&gt;&gt; albumsListIterator = albums.listIterator();
ListIterator&lt;Song&gt; targetAlbumListIterator = targetAlbum.listIterator();
ListIterator&lt;Song&gt; albumSongListIterator;
while(albumsListIterator.hasNext()) {
LinkedList&lt;Song&gt; 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 + &quot; already exists in the Album. please choose\n a different song.&quot;);
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&lt;Song&gt; greenDayAlbum = new LinkedList&lt;&gt;();
greenDayAlbum.add(new Song(&quot;21 Guns&quot;, 3));
greenDayAlbum.add(new Song(&quot;Basket Case&quot;, 3));
greenDayAlbum.add(new Song(&quot;American Idiot&quot;, 3));
LinkedList&lt;Song&gt; linkinParkAlbum = new LinkedList&lt;&gt;();
linkinParkAlbum.add(new Song(&quot;Numb&quot;, 3));
linkinParkAlbum.add(new Song(&quot;In the end&quot;, 3));
linkinParkAlbum.add(new Song(&quot;Castle of glass&quot;, 3));
LinkedList&lt;LinkedList&lt;Song&gt;&gt; albums = new LinkedList&lt;&gt;();
albums.add(greenDayAlbum);
albums.add(linkinParkAlbum);
LinkedList&lt;Song&gt; targetAlbum = new LinkedList&lt;&gt;();
//addSongFromAlbumToAlbum(albums, targetAlbum, &quot;Basket Case&quot;);
findMatchedSongs(albums, targetAlbum, &quot;Basket Case&quot;);
for(Song matchedSong : targetAlbum) {
System.out.println(matchedSong); //outputs Song[title=Basket Case, duration=3]
}
}
private static boolean findMatchedSongs(LinkedList&lt;LinkedList&lt;Song&gt;&gt; inputAlbums, LinkedList&lt;Song&gt; outputAlbum, String searchedTitle) {
if (searchedTitle == null) {
System.out.println(&quot;Provide a title to search for.&quot;);
return false;
}
for (LinkedList&lt;Song&gt; songs : inputAlbums) {
for (Song song : songs) {
if (!searchedTitle.equals(song.getTitle())) {
continue;
}
if (outputAlbum.contains(song)) {
System.out.println(String.format(&quot;Song %s already exists in the album; please choose a different song&quot;, song.getTitle()));
return false;
}
outputAlbum.add(song);
}
}
return true;
}
}
class Album {
private Collection&lt;Song&gt; songs;
public Album(Collection&lt;Song&gt; 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 &amp;&amp; !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(&quot;Song[title=%s, duration=%d]&quot;, title, duration);
}
}

huangapple
  • 本文由 发表于 2020年7月31日 04:23:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/63180844.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定