很抱歉,如果这一切看起来很难理解,但我是编程的新手,我已经查看了几本书和网站,并且根据我的理解,我想要做的事情应该有效。我正在处理的任务是调用类的类。如果不将我的所有代码都放在这里,我将尝试在不明确的区域尽可能具体。空指针异常适用于此特定代码行:
if(CDList[i].getArtist().equals(artist) == true)
// CDList是一个CD对象数组(在另一个类中创建)
// getArtist()是CD类的一个方法,它返回一个String
// equals()中的艺术家是用户输入的Scanner对象,也是一个String
这个特定方法的要点是搜索数组CDList并将存储的艺术家字符串与扫描的艺术家字符串进行比较,然后将其与标题相同。如果找到,则将删除该部分数组的内容。如果有帮助,这是方法的其余部分:
void delete()
{
Scanner input = new Scanner(System.in);
System.out.println("Enter artist and title to be deleted: ");
String artist = input.nextLine();
String title = input.nextLine();
for(int i = 0; i <= numOfCDs; i++)
{
if(CDList[i].getArtist().equals(artist) == true)
{
for(int j = 0; j <= numOfCDs; j++)
{
if(CDList[j].getTitle().equals(title) == true)
{
System.out.println("Found CD: " + CDList[j].getArtist() + " " +
CDList[j].getTitle());
System.out.println("Would you like to delete it? Y/1 N/0 ");
if(input.nextInt() == 1)
{
CDList[j] = null;
numOfCDs--;
}
}
else
System.out.println("CD not found.");
}
}
else
System.out.println("CD not found.");
}
}
对不起,这是剩下的代码。只是觉得它太过分了。
CD类:
package assignment3;
public class CD
{
public String artist;
public String title;
private tracklist listOfTracks = new tracklist();
CD(String artistName, String titleName)
{
artist = artistName;
title = titleName;
}
public String getArtist()
{
return artist;
}
public String getTitle()
{
return title;
}
public boolean addTrack(String trackInfo)
{
boolean result = false;
if(listOfTracks.add(trackInfo) == true)
result = true;
return result;
}
public int numTracks()
{
int count = listOfTracks.count();
return count;
}
public void display()
{
System.out.println(" ");
System.out.println(getArtist() + " : " + getTitle());
listOfTracks.display(7);
}
}
trackList类:
package assignment3;
public class tracklist
{
public String[] tracks;
public int numElements;
tracklist()
{
tracks = new String[99];
numElements = 0;
}
public boolean add(String track)
{
boolean result = true;
int index = 0;
while(tracks[index] != null)
{
index++;
}
tracks[index] = track;
numElements++;
if(numElements > 99)
result = false;
return result;
}
public int count()
{
return numElements;
}
public void display(int indent)
{
for(int i = 1; i < numElements; i++)
{
System.out.print(i);
if(i >= 10)
{
for(int j = 0; j < (indent - 1); j++)
{
System.out.print(" ");
}
}
else
{
for(int j = 0; j < indent; j++)
{
System.out.print(" ");
}
}
System.out.println(tracks[i]);
}
}
}
CDList类:
package assignment3;
import java.util.Scanner;
public class CDList
{
public int numOfCDs;
private CD[] CDList;
private int front,rear;
CDList(int size)
{
CDList = new CD[size];
numOfCDs = 0;
front = 0;
rear = size - 1;
}
boolean add()
{
boolean result;
Scanner input = new Scanner(System.in);
System.out.println("Enter the Artist Name and CD Title: ");
CD userCD = new CD(input.nextLine(), input.nextLine());
System.out.println("Enter the number of tracks: ");
int trackNumber = input.nextInt();
System.out.println("Enter your track titles: ");
for(int i = 0; i <= trackNumber; i++)
{
userCD.addTrack(input.nextLine());
}
if(rear == front)
result = false;
else
{
if(CDList[rear] != null)
rear--;
else
CDList[rear] = userCD;
result = true;
}
return result;
}
void delete()
{
Scanner input = new Scanner(System.in);
System.out.println("Enter artist and title to be deleted: ");
String artist = input.nextLine();
String title = input.nextLine();
for(int i = 0; i <= CDList.length - 1; i++)
{
if((CDList[i].getArtist().equals(artist)) &&
(CDList[i].getTitle().equals(title)))
{
System.out.println("Found CD of: " + CDList[i].getArtist() + " " +
CDList[i].getTitle());
System.out.println("Would you like to delete it? Y/1 N/0 ");
if(input.nextInt() == 1)
{
CDList[i] = null;
numOfCDs--;
}
}
else
System.out.println("CD not found.");
}
}
void SortArtist()
{
CD temp = new CD(" ", " ");
for(int i = 0; i < numOfCDs; i++)
if(CDList[i].getArtist().compareTo(CDList[i + 1].getArtist()) < 0)
{
temp = CDList[i];
CDList[i] = CDList[i + 1];
CDList[i + 1] = temp;
}
}
void SortTitle()
{
CD temp = new CD(" ", " ");
for(int i = numOfCDs; i > 0; i--)
{
int x = 0;
for(int j = 1; j <= i; j++)
{
if(CDList[i].getTitle().compareTo(CDList[i + 1].getTitle()) < 0)
x = j;
}
temp = CDList[x];
CDList[x] = CDList[i];
CDList[i] = temp;
}
}
void Display()
{
for(int i = 0; i <= numOfCDs; i++)
{
while(CDList[i] == null)
i++;
CDList[i].display();
}
}
int size()
{
return numOfCDs;
}
}
答案 0 :(得分:4)
if(CDList[i].getArtist().equals(artist) == true)
如果您正在获得NPE,可以采用以下方式:
CDList
为空CDList[i]
为空CDLIst[i].getArtist()
返回null Artist
会覆盖equals()
并且有一个导致NPE的错误,但在这种情况下,NPE会指向equals()
中的语句。您没有显示类Artist
,因此我们可以看到它是否覆盖equals()
,并且没有发布堆栈跟踪,因此我们可以确切地看到抛出异常的位置。
正如其他人评论的那样,== true
是多余的。
答案 1 :(得分:0)
我建议使用LinkedList<CD>
或ArrayList<CD>
代替CD[]
。
这样您就可以轻松删除项目,如下所示:
LinkedList<CD> cdList = new LinkedList<CD>();
// add items with cdList.add(...);
Iterator<CD> cdListIterator = cdList.iterator();
// Loop while the list still contains elements.
while (cdListIterator.hasNext()) {
CD thisCd = iterator.next();
// do some operation on the cd to tell whether you want to delete it
// for example:
if (thisCd.getArtist().equals(artist) && thisCd.getTitle().equals(title)) {
iterator.remove(); // it's that simple
// Don't have to mess with `cdCount--` or anything.
}
}
而且,正如一些人评论的那样,你不需要a.equals(b) == true
;你可以使用a.equals(b)
。
答案 2 :(得分:0)
条件是否有任何问题。它是你的循环有问题。 使用单个for循环:
for(int i = 0; i <= numOfCDs; i++)
{
if(CDList[i].getArtist().equals(artist) && CDList[i].getTitle().equals(title))
{
System.out.println("Found CD: " + CDList[j].getArtist() + " " + CDList[j].getTitle());
System.out.println("Would you like to delete it? Y/1 N/0 ");
if(input.nextInt() == 1)
{
CDList[i] = null;
// do not do numOfCDs-- here
}
}
}
答案 3 :(得分:0)
这里有很多问题。
NPE的直接原因是内部循环通过将CD分配给null
从列表中“删除”CD,然后外部循环尝试在您刚刚删除的位置测试CD。由于它是null
,因此您尝试将null.getArtist()
称为NPE。
首先要注意的是,您只需要一个循环。循环体应测试您正在查看的CD具有相同的标题和艺术家......
接下来需要注意的是,摆脱额外的循环是不够的。如果多次调用delete()
方法,则第二次调用可能会遇到第一次调用生成的null
条目...并且您将像以前一样获得NPE。测试应该在他们尝试获取标题/艺术家信息之前检查null
; e.g。
CD cd = cdList[i];
if (cd != null &&
cd.getArtist().equals(artist) &&
cd.getTitle().equals(title)) {
// ...
}
此时设计问题变得明显。数组中的这些null
值是糟糕的主意。有三个修复:
您可以通过创建一个较小的元素来删除CD ...并复制除您要删除的CD之外的所有CD。
您可以添加cdListSize
字段,并安排它为您提供列表中有效条目的数量。然后(这是重要的一点),当您从列表中删除条目时,将当前最后一个条目移动到已删除条目所在的位置并递减cdListSize
。如果您一致地执行此操作,null
条目将全部结束,您可以从零迭代到cdListSize - 1
以获取非空条目。
最重要的是,使用List
而不是数组来表示CD列表。 List
API提供了一种删除给定位置条目的方法。方法真的将其删除......它不只是将其设置为null
。
最后,您可能需要退后一步,查看更大的应用程序。 CD列表是否应该保留;例如以便在应用程序重新启动时它仍然可用?它可能很大;例如太大而无法融入记忆?你可能想在CD列表上做复杂的查询吗?所有这些都表明你应该使用数据库而不是内存数据结构。
(但是,使用您刚刚添加的额外代码,很明显超出了您的分配范围。)
答案 4 :(得分:0)