2013-03-12 45 views
0

对不起,如果这一切似乎很难理解,但我是编程新手,我看了几本书和网站,并从我的理解,我想要做的应该工作。我正在做的任务是调用类的类。如果不把我所有的代码放在这里,我会尽量在不明确的地方尽可能具体。空指针的例外是这个代码特定行:NPE在调用equals()

if(CDList[i].getArtist().equals(artist) == true) 

// CDList是CD对象(其在另一个类中创建)的阵列

// getArtist()是的一个方法返回的String

//艺术家按照equals(CD类)是扫描仪对象用户已经inputed,也字符串

此特定方法的要点是通过在阵列CDList搜索和比较将艺术家字符串存储到艺术家Strin中g扫描,然后相同的标题。如果找到,那么该部分数组的内容将被删除。这里是该方法的其余部分,如果它会帮助:

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

曲目类别:

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

不要使用'if(contition == true)'只是使用'if(condition)'。 – Pshemo 2013-03-12 02:56:37

+1

根本不需要'== true'。 – 2013-03-12 02:56:40

+0

请提供一些示例输入和输出。 – 2013-03-12 02:57:14

回答

4
if(CDList[i].getArtist().equals(artist) == true) 

如果您收到NPE,这里的可能性:

  1. CDList是空
  2. CDList[i]是空
  3. CDLIst[i].getArtist()返回null
  4. Artist覆盖equals()并具有导致NPE的一个错误,但在这种情况下,NPE将指向声明equals()

您还没有表现出类Artist,所以我们可以看到,如果它覆盖equals(),并没有张贴堆栈跟踪,所以我们可以清楚地看到抛出异常。

正如其他人所评论的,== true是多余的。

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)

+0

@ user2159150:很高兴听到您找到它。作为最后一点,考虑将你的变量'CDList'重命名为'cdList';在Java中,按照惯例,类以CapitalLetters(例如'String','CD','File')开头,变量名(例如'frame','args','button')被写入camelCase中。这会让你的代码更容易被其他程序员理解。 – wchargin 2013-03-12 03:44:03

0

如果条件没有问题。它的循环有问题。 使用单个循环:

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

这里有很多问题。

您的NPE的直接原因是内部循环通过将CD分配给null“从列表中删除”CD,然后外部循环尝试在刚删除的位置测试CD。既然是null,那么你就试图拨打null.getArtist()哪个NPE。

首先要注意的是,你只需要一个循环。循环体应该测试你正在看的CD具有相同的标题和艺术家...

接下来要注意的是,摆脱额外的循环是不够的。如果delete()方法被多次调用,第二次调用很可能会遇到由第一次调用产生的null条目......并且您将像以前那样获得NPE。在试图获得标题/艺术家信息之前,测试应该检查null;例如

CD cd = cdList[i]; 
if (cd != null && 
    cd.getArtist().equals(artist) && 
    cd.getTitle().equals(title)) { 
    // ... 
} 

在这一点上,设计问题变得明显。这些数组中的null值是坏主意。有三种解决方法:

  • 您可以通过创建更小的一个新的数组一个元素取出光盘......并在所有CD复制从要删除的一个分开。

  • 您可以添加一个cdListSize字段,并安排它为您提供列表中有效条目的数量。然后(这是重要的一点),当您从列表中删除一个条目时,将当前最后一个条目移到删除条目所在的位置,然后递减cdListSize。如果你这样做,null条目将全部结束,并且您可以从零到cdListSize - 1迭代以获得非空条目。

  • 最重要的是,使用List而不是数组来表示CD列表。 List API提供了一种用于删除给定位置处的条目的方法。方法确实删除它......它不只是将其设置为null

最后,您可能需要退后一步,看看更大的应用程序。 CD列表是否应该坚持;例如以便在您的应用程序重新启动时它仍然可用?它可能很大;例如太大以至于不能适应内存?您是否想要在CD列表上执行复杂的查询?所有这些事情都会暗示你应该使用数据库而不是内存数据结构。

(不过,与您刚刚添加额外的代码,很显然,这将是超出你的任务的范围。)

0

找到了!感谢您的意见,我做了一些改变,你会推荐。问题是CDList [i]为空。刚刚实施了一个if(CDList [i] == null),然后继续;感谢您的输入。 -