0

I've been sifting through my code for a project and can't get this method to work as it's designed. What should be happening is that the system searches an array passed as a parameter for a user-inputted value. The following is the entire method as is written (there is some random text I've thrown in for debugging):

    public static void updatePC(int ARRAY_SIZE, int count, String[] customerName, String[] customerID, String[] os, String[] typeOfProblem, int[] turnAroundTime) {
    Scanner keyboard = new Scanner(System.in);
    String toUpdate;
    String[] customerIDClone = new String[count];
    int intToUpdate = -1, loop = count, n;
    char correct = 'n';

    customerIDClone = Arrays.copyOf(customerID, count);
    while (correct == 'n') {
        System.out.println("Please enter the customer ID of the work order you wish to modify");
        toUpdate = keyboard.nextLine();
        if (Arrays.asList(customerIDClone).contains(toUpdate) == true) {
            intToUpdate = Integer.parseInt(toUpdate);
        }
        while (Arrays.asList(customerIDClone).contains(toUpdate) == false) {
            System.out.println("The customer ID you entered was not found. Please try again.");
            toUpdate = keyboard.nextLine();
            intToUpdate = Integer.parseInt(toUpdate);
        }
        System.out.println("Beginning search loop. The value to find is " + toUpdate);
        for (n = 0; n < loop; n++);
        {
            System.out.println("Loop loop looooooooop");
            System.out.println(customerID[n]);
            System.out.println(customerID[0]);
            if (customerID[count].equals(toUpdate)) {
                System.out.println("Found it!");
                count = n;
            }
        }

        System.out.println("Testing run 1.");
    }
    System.out.println("");
    System.out.println("--");
    System.out.println("                    Name:  " + customerName[count]);
    System.out.println("             Customer ID:  " + customerID[count]);
    System.out.println("                      OS:  " + os[count]);
    System.out.println("         Type of Problem:  " + typeOfProblem[count]);
    System.out.println("Expected Turnaround Time:  " + turnAroundTime[count]);
    System.out.println("--");
    System.out.println("Is this new record correct? Please enter y or n.  ");
    correct = keyboard.next().charAt(0);
    keyboard.nextLine();
}

I've been sorting through other questions here on the site and elsewhere, but I can't figure out the issue. The output of the method is

Please enter the customer ID of the work order you wish to modify
3
Beginning search loop. The value to find is 3
Loop loop looooooooop
null
1
Exception in thread "main" java.lang.NullPointerException
    at mckelvey_project3.McKelvey_Project3.updatePC(McKelvey_Project3.java:183)
    at mckelvey_project3.McKelvey_Project3.main(McKelvey_Project3.java:45)
Java Result: 1
BUILD SUCCESSFUL (total time: 7 seconds)

I wrote the line

System.out.println(customerID[0]);

into my code just to demonstrate and make sure that the array is defined and initialized. Additionally,

System.out.println(customerID[1]);

is also defined. It seems the problem exists within my loop test; running

System.out.println(loop + count + n)

reveals that they are all equal to 3. Where is n getting set to 3 at?

EDIT Added the following code suggested by @hfontanez

        customerIDClone = Arrays.copyOf(customerID, count);
    for (int i = 0; i < count; i++) {
        if (customerIDClone[i] == null) {
            System.out.println("Element " + i + " is null. Creating new String.");
            customerIDClone[i] = new String();
        }

and the output is as follows:

Please enter the customer ID of the work order you wish to modify
3
Beginning search loop. The value to find is 3
Loop loop looooooooop
null
2
Exception in thread "main" java.lang.NullPointerException
    at mckelvey_project3.McKelvey_Project3.updatePC(McKelvey_Project3.java:190)
    at mckelvey_project3.McKelvey_Project3.main(McKelvey_Project3.java:45)
Java Result: 1
BUILD SUCCESSFUL (total time: 14 seconds)

EDIT 2 I found the problem... I had a stray ; here:

for (n = 0; n < count; n++);

This issue is now solved.

  • BTW, `if(Arrays.asList(customerIDClone).contains(toUpdate) == true)` is the same as `if(Arrays.asList(customerIDClone).contains(toUpdate))` – hfontanez Nov 26 '14 at 18:21
  • Ah, thanks for the tip. Changing my code now. Would that also apply to while (Arrays.asList(customerIDClone).contains(toUpdate) == false) being able to be written as while (!Arrays.asList(customerIDClone).!contains(toUpdate)) ? –  Nov 26 '14 at 18:24
  • Change this as well: `while (Arrays.asList(customerIDClone).contains(toUpdate) == false)` to `while (!Arrays.asList(customerIDClone).contains(toUpdate))` – hfontanez Nov 26 '14 at 18:26
  • Okay, cool. Dumb questions, but I can't seem to get the four space formatting for code in comments to work.. what am I missing? –  Nov 26 '14 at 18:30
  • Enclose the code with accent character (tilde) to the left of the #1 key – hfontanez Nov 26 '14 at 18:31
  • Sorry, I don't see why this is a duplicate. I searched through the other questions, but none of the solutions seemed to solve this problem. –  Nov 26 '14 at 18:36
  • `customerID` and `customerIDClone` are arrays of different lengths. It appears that the clone is larger than the original. In such cases, the additional positions are initialized with NULL. Instantiating an array ONLY reserves memory of the declared indices. It DOES NOT initialize each element with an Object type. – hfontanez Nov 26 '14 at 18:53

1 Answers1

1

An array in Java is an object. When you create an array of objects, for instance an array of Strings, you must initialize the array AND each element. The line:

String[] customerIDClone = new String[count];

Initializes an array of 'COUNT' number of String objects, but each element is still null. That is why you are getting a null pointer exception.

Before you invoke customerID[count].equals(toUpdate), the (String) element at customerID[count] must be properly instantiated.

The problem in this case is that the new array is not an exact copy of the original. This line:

customerIDClone = Arrays.copyOf(customerID, count);

Creates a new array of 'COUNT' length. If 'COUNT' is more than the length of the original, all newly created elements are padded with NULL. This explains why customerID[0] works, but not customerID[n]. To fix this, you can iterate through the new array and add a new String() to each NULL element.

UPDATE:

Try this:

customerIDClone = Arrays.copyOf(customerID, count);
for (int i = 0; i < count; i++)
{
    if(customerIDClone[i] == null)
    {
        System.out.println("Element " + i + " is null. Creating new String.");
        customerIDClone[i] = new String();
    }
}
hfontanez
  • 5,774
  • 2
  • 25
  • 37
  • But isn't it initialized by `customerIDClone = Arrays.copyOf(customerID, count);` –  Nov 26 '14 at 18:29
  • Also, my search loop uses customerID rather than customerIDClone –  Nov 26 '14 at 18:31
  • No... If the new array is larger than the original array, the new elements are padded with NULL. See the [API Arrays.copyOf()](https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#copyOf%28T[],%20int%29). In your case, it seems the original array only has a single element; which is why `customerID[0]` works. – hfontanez Nov 26 '14 at 18:36
  • Just tested this theory, but customerID[1] & customerID[2] are both correctly defined. Besides, even though the first loop test passes, the value is still listed as 'null' –  Nov 26 '14 at 18:41
  • This is not a theory. This is a fact stipulated on the API. Go to the link I provided a few comments above. – hfontanez Nov 26 '14 at 18:43
  • If this fixed your problem, I would appreciate if you mark this answer as such. – hfontanez Nov 26 '14 at 18:54
  • EDIT: Didn't see your change, testing now. –  Nov 26 '14 at 18:56
  • I tried the changes you listed in your update, but the problem still persists. –  Nov 26 '14 at 19:17