简体   繁体   English

搜索并从数组中删除项目

[英]Search and remove item from array

Does anyone why when the search value matches a value stored in array it doesn't remove that item? 有人为什么在搜索值与数组中存储的值匹配时不会删除该项目?

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:");
} 

Many things are wrong with this code: 此代码有很多错误:

  1. You never update titles and lengths inside your while loop, so whatever happens inside has no effect on what's printed in the dialog 您永远不会在while循环中更新titleslengths ,因此内部发生的任何事情都不会影响对话框中的输出
  2. When you find song title to remove, you copy the next song title to the current one, but don't copy anything else, so [a, b, c, d] will after removing b change to [a, c, c, d] - you need to shift everything behind the deleted element left by one position 当您找到要删除的歌曲名称时,您将下一首歌曲名称复制到当前歌曲名称,但不复制其他任何内容,因此[a, b, c, d]在删除b后将更改为[a, c, c, d] -您需要将已删除元素后面的所有内容向左移动一个位置
  3. When you find song title to remove, you assume the i+1 th position is valid - this isn't true if you remove the last song on the list, that would either fail with ArrayIndexOutOfBounds exception or copy some garbage from behind the currently valid playlist 当您找到要删除的歌曲标题时,您认为第i+1个位置是有效的-如果您删除列表中的最后一首歌曲,则不正确,否则可能会由于ArrayIndexOutOfBounds异常而失败,或者从当前有效的歌曲后面复制一些垃圾播放列表
  4. You're never updating songLengths array 您永远不会更新songLengths数组
  5. Concatenating strings in a loop using += is very ineffective - use StringBuilder instead 使用+=在循环中连接字符串非常无效-改用StringBuilder

Sorry this took a while, but hopefully it's pretty comprehensive. 抱歉,这花了一段时间,但希望它相当全面。

I am assuming that song title and song length are supposed to correspond with one another, so that if you remove the title you also remove the length? 我假设歌曲的标题和歌曲的长度应该相互对应,因此,如果删除标题,那么长度也应该删除吗? It may be good to create a class, eg Song, which has a field for both title and length. 创建一个类(例如Song)可能会很好,该类同时具有标题和长度字段。 There are more methods you can add, eg setters, default constructor, etc. You can also include more fields like Song Artist, year, etc. I'm just including those required for your program to run. 您可以添加更多方法,例如,setter,默认构造函数等。您还可以包括更多字段,例如Song Artist,year等。我只包括程序运行所需的那些。

I'll use red's suggestion of an ArrayList, so you can see what they meant (in case you haven't learned what that is) 我将使用red的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";
    }

From here, in your main method you can do... 从这里开始,您可以使用主要方法...

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. ;)

Then we create objects and add them to your list like so: 然后,我们创建对象并将其添加到您的列表中,如下所示:

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

Once you have your playlist set up, we return to your question regarding song removal, and here is where Lists(there are different ones you can use)/Objects really make things far simpler. 设置好播放列表后,我们将返回有关删除歌曲的问题,这就是列表(可以使用不同的列表)/对象使事情变得简单得多的地方。

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

And printing is simple too. 而且打印也很简单。

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

-EDIT- -编辑-

To put into perspective, here is what you would have to do for removal in your program using array and without objects. 透视一下,这是在使用数组且没有对象的情况下在程序中删除所要做的。

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

Suffice it to say, this is much more ugly, and there's many more places where you can make a stupid mistake that may or may not throw an exception. 可以这么说,这很丑陋,还有很多地方可以犯一个愚蠢的错误,可能会或可能不会引发异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM