Как я могу удвоить размер массива без получения NullPointException? - PullRequest
0 голосов
/ 07 октября 2018

Во-первых, для краткости, вот мой вчерашний пост:

Как обойти исключение NullPointerException в Java?

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

static String[] upSizeArr( String[] fullArr )
{

    int size = fullArr.length; 
    String[] newSizeArr = new String[(2 * size)]; 
    for (int a = 0; a < size; a++) {
        newSizeArr[a] = fullArr[a];
    }
    return newSizeArr;
}

и затем использую этот метод в контексте этого цикла while:

static final int CAPACITY = 10;
int wordCount = 0;

BufferedReader wordFile = new BufferedReader( new FileReader(args[1]) );
String[] wordList = new String[CAPACITY];

while ( wordFile.ready() ) 
    {   if ( wordCount == wordList.length ) 
            wordList = upSizeArr( wordList );
        wordList[wordCount++] = wordFile.readLine();
    } 
wordFile.close();

Можно ли обойти это, используя метод upSizeArr?Я бы предпочел, чтобы решение было базовым и использовало только массивы без других структур данных.Я новичок в программировании и действительно пытаюсь понять основы ... искал решение этой исключительной ситуации NullPointException примерно неделю назад.

Вот код целиком:

import java.io.*;
import java.util.*;
public class Practice
{
    static final int CAPACITY = 10;
    static final int NOT_FOUND = -1;
    public static void main (String[] args) throws Exception
    {
        if (args.length < 1 )
        {
            System.out.println("\nusage: C:\\> java Practice <words filename>\n\n"); // i.e. C:\> java Lab2 10Kints.txt 172822words.txt
            System.exit(0);
        }


    String[] wordList = new String[CAPACITY];
    int wordCount = 0;
    BufferedReader wordFile = new BufferedReader( new FileReader(args[0]) );

    while ( wordFile.ready() ) // i.e. while there is another line (word) in the file
    {   if ( wordCount == wordList.length ) 
            wordList = upSizeArr( wordList );
        wordList[wordCount++] = wordFile.readLine();
    } //END WHILE wordFile
    wordFile.close(); 
    System.out.format( "%s loaded into word array. size=%d, count=%d\n",args[0],wordList.length,wordCount );
    int dupeIndex = indexOfFirstDupe( wordList, wordCount );
    if ( dupeIndex == NOT_FOUND )
        System.out.format("No duplicate values found in wordList\n");
    else
        System.out.format("First duplicate value in wordList found at index %d\n",dupeIndex);

} // END OF MAIN

// TWO METHODS 

static String[] upSizeArr( String[] fullArr )
{

    int size = fullArr.length; //find the length of the arrays
    String[] newSizeArr = new String[(2 * size)]; // creates new array, doubled in size
    for (int a = 0; a < size; a++) {
        newSizeArr[a] = fullArr[a];
    }
    return newSizeArr;

}
static int indexOfFirstDupe( String[] arr, int count )
{       
    Arrays.sort(arr);
    int size = arr.length;
    int index = NOT_FOUND;

    for (int x = 0; x < size; x++) {
        for (int y = x + 1; y < size; y++) {
            if (arr[x].equals(arr[y])) {
                index = x;
                break;
            }
        }
    }
    return index;
    }
} // END OF PROGRAM

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

1 Ответ

0 голосов
/ 07 октября 2018

Я не уверен, является ли это причиной вашей проблемы, но это очень подозрительно ...

while ( wordFile.ready() ) {
    //...
}

не так, как вы должны читать файл.Вместо этого вы должны проверить результат возврата readLine, который вернет null, когда он достигнет конца файла.

Может быть, что-то более похожее на ....

try (BufferedReader wordFile = new BufferedReader(new FileReader(args[1]))) {
    String[] wordList = new String[CAPACITY];

    String text = null;
    while ((text = wordFile.readLine()) != null) {
        if (wordCount == wordList.length) {
            wordList = upSizeArr(wordList);
        }
        wordList[wordCount++] = text;
    }
} catch (IOException ex) {
    ex.printStackTrace();
}

Ваш код также рискует оставить ресурс файла открытым.В приведенном выше примере оператор try-with-resources используется для обеспечения его правильного закрытия независимо от успеха операции.

Взгляните на Оператор попытки с ресурсами для получения более подробной информации.

Если это не является особым требованием, я бы также рекомендовал использовать ArrayList или System.arraycopy для прокрутки собственного решения, подобного этому.

Возможнопосмотрите Список реализаций для получения более подробной информации

Обновление из запускаемого примера ...

После воспроизведения без запускаемого примера кода, когда upSizeArr создает новый массив, он по умолчанию устанавливает новые элементы в null, что ожидается, я удивлен, что Arrays.sort не может справиться с этим.

"A" решение - заполнить неиспользуемое пространствос другим значением, отличным от значения по умолчанию ...

static String[] upSizeArr(String[] fullArr) {

    int size = fullArr.length; //find the length of the arrays
    String[] newSizeArr = new String[(2 * size)]; // creates new array, doubled in size
    for (int a = 0; a < size; a++) {
        newSizeArr[a] = fullArr[a];
    }
    for (int a = size; a < newSizeArr.length; a++) {
        newSizeArr[a] = "";
    }
    return newSizeArr;

}

"Другое" решение может заключаться в "уменьшении размера" массива в соответствии с доступными данными ...

static String[] downsizeToCapacity(String[] fullArr) {
    int lastIndex = 0;
    while (lastIndex < fullArr.length && fullArr[lastIndex] != null) {
        lastIndex++;
    }
    if (lastIndex >= fullArr.length) {
        return fullArr;
    }
    String[] downSized = new String[lastIndex];
    System.arraycopy(fullArr, 0, downSized, 0, lastIndex);

    return downSized;
}

Все этопытается сделать, это создать новый массив, размер которого только большойдостаточно содержать все ненулевые значения и возвращать их.

Затем вы можете использовать что-то вроде ...

System.out.format("%s loaded into word array. size=%d, count=%d\n", "words.txt", wordList.length, wordCount);
wordList = downsizeToCapacity(wordList);
System.out.format("%s loaded into word array. size=%d, count=%d\n", "words.txt", wordList.length, wordCount);

int dupeIndex = indexOfFirstDupe(wordList, wordCount);

, которое в моем тестировании выдает

words.txt loaded into word array. size=160, count=99
words.txt loaded into word array. size=99, count=99
No duplicate values found in wordList
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...