NullPointerException из пустых ячеек массива

Используя Java и не IDE, а скорее командную строку, я должен написать простую программу телефонной книги, ориентированную на массивы, в которой у пользователя есть три варианта: найти имя в массиве и распечатать имя и номер телефона. если имя найдено, добавьте новое имя и номер телефона в массив на основе пользовательского ввода и удалите имя и номер из массива на основе пользовательского ввода. Функция добавления работает именно так, как должна, но функции поиска и удаления работают неправильно. Мой код компилируется и запускается, но я получаю ошибку времени выполнения NullPointerException всякий раз, когда пытаюсь найти или удалить имя, которого нет в массиве.

Это конкретные инструкции для части программы «удалить запись»:

"Чтобы удалить имя и номер из такого массива, сначала найдите ячейку с именем. Если удаляемого имени нет в массиве, сообщите об ошибке. Теперь скопируйте ссылку из последней непустой ячейки в удаленную имя ячейки. Установите для последней ненулевой ячейки значение null. Теперь удаленный PhoneEntry является мусором, и весь массив все еще имеет все нули в конце."

Вот мой код:

import java.util.*;

class PhoneEntry
{
    String name;    // name of a person
    String phone;   // their phone number

    PhoneEntry( String n, String p )
    {
        name = n; phone = p;
    }
}

class PhoneBook
{
    PhoneEntry[] phoneBook;

    PhoneBook()    // constructor
    {
        phoneBook = new PhoneEntry[ 10 ] ;

        phoneBook[0] = new PhoneEntry( "James Barclay", "(418) 665-1223" );
        phoneBook[1] = new PhoneEntry( "Grace Dunbar",  "(860) 399-3044" );
        phoneBook[2] = new PhoneEntry( "Paul Kratides", "(815) 439-9271" );
        phoneBook[3] = new PhoneEntry( "Violet Smith",  "(312) 223-1937" );
        phoneBook[4] = new PhoneEntry( "John Wood",     "(913) 883-2874" );
        phoneBook[5] = new PhoneEntry( null, null );
        phoneBook[6] = new PhoneEntry( null, null );
        phoneBook[7] = new PhoneEntry( null, null );
        phoneBook[8] = new PhoneEntry( null, null );
        phoneBook[9] = new PhoneEntry( null, null );
    }

    PhoneEntry search( String targetName )
    {
        for ( int i = 0 ; i < phoneBook.length ; i++ )
        {
            System.out.println(i);  // debug
            if ( phoneBook[i] != null && phoneBook[i].name.equals( targetName ) )
            {
                return phoneBook[i];
            }
        }
        return null;
    }

    PhoneEntry addEntry( String addName, String addNumber )
    {
        boolean found = false;
        for ( int i = 0 ; i < phoneBook.length ; i++ )
        {
            System.out.println(i);  // debug
            if ( phoneBook[i].name == null )
            {
                phoneBook[i] = new PhoneEntry( addName, addNumber );
                found = true;
                    break;
            }
        }
        if ( !found )
        {
            System.out.println("Phone book is full! Delete an entry first!");
        }
        return null;
    }

    PhoneEntry deleteEntry( String deleteName )
    {
        boolean found = false;
        for ( int i = 0 ; i < phoneBook.length ; i++ )
        {
            System.out.println(i);  // debug
            if ( phoneBook[i] != null && phoneBook[i].name.equals( deleteName ) )
            {
                System.out.println( phoneBook[i].name + " found");  // debug
                phoneBook[i] = new PhoneEntry( null, null );
                found = true;
                    break;
            }
        }
        if ( !found )
        {
            System.out.println( "Entry not found." );
        }
        return null;
    }
}

class PhoneBookComplete
{
    public static void main ( String[] args )
    {
        PhoneBook pb = new PhoneBook();
        Scanner scan = new Scanner( System.in );
        String tempName, tempNumber, tempDelName;

            // INITIAL WELCOME MESSAGE START

        System.out.println();
        System.out.println("**********************");
        System.out.println("***** PHONE BOOK *****");
        System.out.println("**********************");
        System.out.println();
        System.out.println(" 1  Search for an entry");
        System.out.println(" 2  Add a new entry");
        System.out.println(" 3  Delete an entry");
        System.out.println(" 4  Quit program");
        System.out.println();
        System.out.print("Enter a command: ");

        String userInput = scan.nextLine();
        PhoneEntry entry;
        System.out.println();

            // INITIAL WELCOME MESSAGE END

        while ( userInput != "quit" )
        {
            if ( userInput.equals("1") )        //  NAME SEARCH
            {
                    System.out.println("    NAME SEARCH START");
                System.out.println("**********************");
                System.out.println("***** NAME SEARCH ****");
                System.out.println("**********************");
                System.out.println();
                System.out.print("Enter a name: ");
                userInput = scan.nextLine();
                entry = pb.search( userInput );

                if ( entry != null )
                {
                    System.out.println();
                    System.out.println( "  " + entry.name + ": " + entry.phone );
                    System.out.println();
                }
                else if ( userInput.equals("quit") )
                {
                    break;
                }
                else
                {
                    System.out.println("Name not found.");
                    System.out.println();
                }
                    System.out.println("    NAME SEARCH END");
                    System.out.println();
            }
            else if ( userInput.equals("2") )   //  ADD ENTRY
            {
                    System.out.println("    ADD ENTRY START");

                System.out.println("**********************");
                System.out.println("***** ADD ENTRY ******");
                System.out.println("**********************");
                System.out.println();

                System.out.print("Enter full name: ");
                tempName = scan.nextLine();

                    if ( userInput.equals("quit") )
                    {
                        break;
                    }

                System.out.print("Enter phone number: ");
                tempNumber = scan.nextLine();

                    if ( userInput.equals("quit") )
                    {
                        break;
                    }

                entry = pb.addEntry( tempName, tempNumber );

                System.out.println();
                System.out.println( "Entry for " + tempName + " successfully added." );
                //System.out.println("Phone book is full! Delete an entry first!");

                    System.out.println("    ADD ENTRY END");
                    System.out.println();
            }
            else if ( userInput.equals("3") )   //  DELETE ENTRY
            {
                    System.out.println("    DELETE ENTRY START");

                System.out.println("**********************");
                System.out.println("**** DELETE ENTRY ****");
                System.out.println("**********************");
                System.out.println();

                System.out.print("Enter full name: ");
                tempDelName = scan.nextLine();
                entry = pb.deleteEntry( tempDelName );

                if ( entry == null )
                {
                    System.out.println();
                    System.out.println( "Entry for " + tempDelName + " successfully deleted." );
                    System.out.println();
                }
                else if ( userInput.equals("quit") )
                {
                    break;
                }
                else
                {
                    System.out.println();
                }

                    System.out.println("    DELETE ENTRY END");
                    System.out.println();
            }
            else if ( userInput.equals("4") )   //  QUIT PROGRAM
            {
                    System.out.println();
                break;
            }

            //System.out.println("Select a command:");
            System.out.println("**********************");
            System.out.println("**********************");
            System.out.println("**********************");
            System.out.println();
            System.out.println(" 1  Search for an entry");
            System.out.println(" 2  Add a new entry");
            System.out.println(" 3  Delete an entry");
            System.out.println(" 4  Quit program");
            System.out.println();
            System.out.print("Enter a command: ");
            userInput = scan.nextLine();
        }
        System.out.println("Goodbye.");
    }
}

Вот ошибка, которую я получаю, когда пытаюсь найти несуществующее имя:

Exception in thread "main" java.lang.NullPointerException
        at PhoneBook.search(PhoneBookComplete.java:39)
        at PhoneBookComplete.main(PhoneBookComplete.java:128)

И вот ошибка, которую я получаю, когда пытаюсь удалить несуществующее имя:

Exception in thread "main" java.lang.NullPointerException
        at PhoneBook.deleteEntry(PhoneBookComplete.java:73)
        at PhoneBookComplete.main(PhoneBookComplete.java:193)

Я знаю, что это как-то связано с тем, что я использую null, но что еще, черт возьми, я мог бы использовать вместо null? Кроме того, я предполагаю использовать null в любом случае.

Итак, я думаю, мой вопрос: что нужно изменить в моем коде, чтобы при попытке пользователя удалить или выполнить поиск несуществующего имени печаталось сообщение об ошибке без сбоя программы?

При ответе имейте в виду, что я очень новичок в Java, и массивы, методы и еще много чего меня все еще сбивают с толку. Если требуется дополнительная информация и т. д., пожалуйста, спросите, и вы получите. С учетом сказанного, любая помощь и объяснения чего бы то ни было ценятся и более чем приветствуются. Спасибо!


person Marth8880    schedule 15.12.2014    source источник


Ответы (2)


Убедитесь, что имя также не null, это

if (phoneBook[i] != null && phoneBook[i].name.equals(targetName))

должно быть что-то вроде

if (phoneBook[i] != null && targetName.equals(phoneBook[i].name))

а в deleteEntry нравится

if (phoneBook[i] != null && deleteName.equals(phoneBook[i].name))

потому что, когда phoneBook[i].name является null, это заставляет NullPointerException вызывать .equals() на нем. Вы также можете добавить null тест на .name, но тогда вам понадобится еще один && лайк

if (phoneBook[i] != null && phoneBook[i].name != null &&
    phoneBook[i].name.equals(targetName))
person Elliott Frisch    schedule 15.12.2014
comment
Ты волшебник? Боже мой, да! Это работает отлично. Большое спасибо! - person Marth8880; 15.12.2014

Кажется, я нашел твою проблему.

if ( phoneBook[i] != null && phoneBook[i].name.equals( deleteName ) )

Это проверяет, является ли запись нулевой, но не проверяет фактическое имя, чтобы увидеть, является ли оно нулевым.

Так должно быть

if ( phoneBook[i].name != null && phoneBook[i].name.equals( deleteName ) )

Код будет работать, если вместо

phoneBook[5] = new PhoneEntry( null, null );

Ты использовал

phoneBook[5] = null;
person Blubber    schedule 15.12.2014