从数组中搜索和删除项目

时间:2015-10-28 14:48:19

标签: java

有人为什么当搜索值与存储在数组中的值匹配时,它不会删除该项?

String titles = "";
String lengths = "";

for (int i = 0; i < numOfSongs; i++) {
    titles += songTitles[i] + " ";
    lengths += songLengths[i] + " ";
}

String search = JOptionPane.showInputDialog("Enter a song title to remove it or -1 to end:");

while (!search.equals("-1")) {  
    for (int i = 0; i < numOfSongs; i++) {
        if (search.equalsIgnoreCase(songTitles[i])) {
            songTitles[i] = songTitles[i + 1];
        }
    }
    numOfSongs--;

    JOptionPane.showMessageDialog(null, "**Current Playlist**" + "\nSong titles: " + titles + "\nSong lengths: " + lengths);

    search = JOptionPane.showInputDialog("Enter a song title to remove it or -1 to end:");
} 

2 个答案:

答案 0 :(得分:1)

此代码存在许多问题:

  1. 您永远不会在while循环中更新titleslengths,因此内部发生的任何事情都不会影响对话框中打印的内容
  2. 当您找到要删除的歌曲标题时,您将下一首歌曲标题复制到当前歌曲标题,但不要复制任何其他标题,因此[a, b, c, d]b删除后更改为[a, c, c, d] - 你需要将被删除元素后面的所有内容移到一个位置
  3. 当您找到要删除的歌曲标题时,您认为i+1位置有效 - 如果您删除列表中的最后一首歌曲,则会失败并且ArrayIndexOutOfBounds例外失败或者从当前有效的播放列表后面复制一些垃圾
  4. 您永远不会更新songLengths数组
  5. 使用+=在循环中连接字符串非常无效 - 使用StringBuilder代替

答案 1 :(得分:1)

对不起,这需要一段时间,但希望它非常全面。

我假设歌曲的标题和歌曲长度应该相互对应,所以如果删除标题你也删除了长度?创建一个类可能是好的,例如歌曲,有标题和长度的字段。您可以添加更多方法,例如setters,默认构造函数等。您还可以包含更多字段,如歌曲艺术家,年份等。我只包括您的程序运行所需的字段。

我会使用红色建议的ArrayList,这样你就可以看到它们的意思了(如果你还没知道那是什么)

public class Song {
    String title; //these are known as fields, or instance variables
    String length;

    public Song(String title, String length) {
        this.title = title;
        this.length = length;
    }

    public String getTitle() {
        return title;
    }

    public String getLength() {
        return length;
    }

    //you can format this differently. Just keeping it simple though. If you don't include toString() method in this class, you will run into some problems if you try to print the object itself. 
    public String toString() {
        return "title = " + title + " length = " + length + "\n";
    }

从这里开始,您可以使用主要方法...

ArrayList<Song> playlist = new ArrayList<>();

//here, inside a do-while loop, get input for each song, then store into strings, let's call them songTitle and songLength. I'm not showing this step since I don't know where you want the input to come from, but I'm sure you can figure this bit out. ;)

然后我们创建对象并将它们添加到您的列表中,如下所示:

Song song = new Song(songTitle, songLength); //creates a new object with arguments songTitle and songLength
playlist.add(song); //adds object to array list.

一旦你设置了播放列表,我们就会回到你关于删除歌曲的问题,这里是列表(你可以使用不同的列表)/对象真的让事情变得简单。

Iterator<Song> songIt = playlist.iterator();
while (!search.equals("-1") && songIt.hasNext()) {
    if (search.equalsIgnoreCase(songIt.next().getTitle())) {
        songIt.remove();
    }
}

印刷也很简单。

for (int i = 0; i < playlist.size(); i++) {
    System.out.println(playlist.get(i);
}

- 编辑 -

从透视角度来看,这是使用数组和没有对象在程序中删除的必要条件。

int removeCount = 0;
while (!search.equals("-1")) {
    for (int i = 0; i < songTitles.length; i++) {
        if (search.equalsIgnoreCase(songTitles[i])) {
             for (int j = i; j < songTitles.length - 1; j++) {
                songTitles[j] = songTitles[j + 1];
                songLengths[j] = songLengths[j + 1];
                removeCount ++;
            }
        }
    }
}

String remainingTitles[] = new String[songTitles.length - removeCount];
String remainingLengths[] = new String[songTitles.length - removeCount];
for (int i = 0; i < temp.length; i++) {
    remainingTitles[i] = songTitles[i];
    remainingLengths[i] = songLengths[i];
}

我只想说,这更难看,并且还有更多的地方可以制造一个可能会或可能不会引发异常的愚蠢错误。