Nullpointerexception with java bubble sort - java

I have been working on a project for way to long now and I am running into a nullpointerexception. I understand that it is when an object is pointing to nothing. I am getting this error while doing a bubble sort in Java. I can't figure out what is causing this exception and thus can't resolve it. The purpose of this code is to sort an array of student ID numbers in a specific order, I've chosen descending order.
public static void idNumber()
{
String[] iD = new String[150]; //array for ID Numbers
//System.out.println("Original order");
for(int i = 0; i < nNumStudents; i++) //add ID numbers to array iD
{
iD[i] = srStudents[i].getStudentKey();
//System.out.println(srStudents[i].getStudentKey());
}
//bubble sort
int k =0;
int j =0;
boolean exchange = true;
String temp;
temp = new String();
while ((k < iD.length - 1) && exchange)
{
exchange = false;
k++;
for(j = 0; j < iD.length - k; j++)
{
if(iD[j].compareTo(iD[j + 1]) > 0)
{
temp = iD[j];
iD[j] = iD[j + 1];
iD[j + 1] = temp;
exchange = true;
}
}
}
System.out.println(iD);
}
Exception in thread "main" java.lang.NullPointerException
at java.lang.String.compareTo(String.java:1139)
at StudentRegistrar.idNumber(StudentRegistrar.java:152)
at Sort.main(Sort.java:21)

From a glance at your code, my guess is that it is possible that your array size exceeds the number of students. If this is the case, you are attempting to compare empty slots in the array, which would give a null pointer exception. To fix this, increment to nNumStudents rather than to the full length of the array.

This nullpointer is coming up because all the members of String array String[] iD = new String[150]; are not initialize for example the for loop which is populating this iD array is either not running until 150 or one of its members is initialized with null so
First thing print and check what is the value of nNumStudents it should be 150. Then make sure that every value which is assigned to iD array is a non null value you can do this by modifying your code to print all the values it is assigned to
for(int i = 0; i < nNumStudents; i++) //add ID numbers to array iD
{
iD[i] = srStudents[i].getStudentKey();
//uncomment the below line and see if it doesn't print null
System.out.println(srStudents[i].getStudentKey());
}
if it exceeds 150 then you will get an ArrayIndexoutofbound exception not null pointer

Related

Can a variable be used as the array index in Java?

I have an array of objects that I am trying to add new objects to the first available 'null' location in the array. However, I am running into a runtime error whenever I attempt to add an object to the array. The error is :
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -211
at Pokedex.addPokemon(Pokedex.java:37)
at Project4.main(Project4.java:36)
The questionable code in the Pokedex class is:
public void addPokemon(Pokemon pkm){
int blankSpace = 0;
for (int i = 0; i < billsPC.length; i++){
if(billsPC[i] == pkm)
System.out.println("Your Pokedex is already storing that Pokemon!");
else{
for(int j = 0; j < billsPC.length; j++){
if(billsPC[j] == null)
blankSpace++;
}
if(blankSpace == 0)
System.out.println("Your Pokedex is already holding the max amount!");
}
}
int dexLoc;
if (blankSpace == billsPC.length)
dexLoc = 0;
else
dexLoc = billsPC.length - blankSpace - 1;
//Line 37 is below
billsPC[dexLoc] = pkm;
}
The questionable code from the Project4 class (line 36) is:
kantoDex.addPokemon(pkm);
where pkm is a set Pokemon object and kantoDex is a set Pokedex object.
The main problem is the nested loops. They cause blankSpace to increment too many times. As such billsPC.length - blankSpace - 1 becomes a number much lesser than 0.
The answer to your question is yes, variables can be used as the array index in Java.
I suspect this method might perform what you want:
public boolean addPokemon(Pokemon pkm) {
for (int i = 0; i < billsPC.length; i++) {
if (billsPC[i] == pkm) {
System.out.println("Your Pokedex is already storing that Pokemon!");
return false;
}
if (billsPC[i] == null) {
for (int j = i + 1; j < billsPC.length; j++) {
if (billsPC[j] == pkm) {
System.out.println("Your Pokedex is already storing that Pokemon!");
return false;
}
}
billsPC[i] = pkm;
return true;
}
}
System.out.println("Your Pokedex is already holding the max amount!");
return false;
}
The method will add pkm to the first nullelement of billsPC should such an element exist. If billsPC already contains pkm or no null element, it will print a message. Finally, it will return true if and only if pkm was successfully added to billsPC, else false.
Yes it can, indeed you are using it before (billsPC[i]).
The problem in your code, as the exception suggests, is that you are trying to access an array location out of bounds, in this case with index -211.
Can a variable be used as the array index in Java? yes but it should be in the bounds of array. billsPC[-1] = pkm;//wrong

Suggestions for my Selection Sort / Java

My Selection Sort algorithm is not working.
I am getting the following errors:
//Exception in thread "main" java.lang.NullPointerException
Note: this is for a java class. I do not have a lot of experience. I am done with the assignment. I am trying to understand the reason why my sorting algorithm isn't working.
Any suggestions on how to correct the problem? Tips?
Corrections? ... any help at all will be appreciated.
Here is my code:
private void sortFlowers(String flowerPack[]) {
// TODO: Sort the flowers in the pack (No need to display them here) - Use Selection or Insertion sorts
// NOTE: Special care is needed when dealing with strings! research the compareTo() method with strings
for(int i = 0; i < flowerPack.length; i++){
String currentMinFlow = flowerPack[i];
int minIndex = i;
for(int j = i; j < flowerPack.length; j++){
if(currentMinFlow.compareToIgnoreCase(flowerPack[j]) <0){
currentMinFlow = flowerPack[j];
minIndex = j;
}
}
if(minIndex != i){
flowerPack[minIndex] = flowerPack[i];
flowerPack[i] = currentMinFlow;
}
}
}
Exception:
Exception in thread "main" java.lang.NullPointerException at
java.lang.String$CaseInsensitiveComparator.compare(String.java:1181) at
java.lang.String$CaseInsensitiveComparator.compare(String.java:1174) at
java.lang.String.compareToIgnoreCase(String.java:1227) at
Assignment01Driver.sortFlowers(Assignment01Driver.java:112) at
Assignment01Driver.<init>(Assignment01Driver.java:37) at
Assignment01Driver.main(Assignment01Driver.java:5)
The issue is coming from the fact that your array was created with a fixed size.
String[] flowerPack = new String[25];
When you create an array of reference type variables, each variable will be initialized with a value of null. If you call the sortFlowers method before each variable is given a value, you run into an issue.
for(int i = 0; i < flowerPack.length; i++){
String currentMinFlow = flowerPack[i];
In the above segment, you are iterating through all 25 positions in the array, including the values that still have a value of null. Then, the following line causes the error:
if(currentMinFlow.compareToIgnoreCase(flowerPack[j]) <0){
Since you are iterating through the entire array, you end up with values of currentMinFlow that are null. If you try to make a method call on a null reference value, you end up with a NullPointerException.
Generally, you rarely want to use fixed size arrays when you're unsure of how many data items you're likely to have. In this case, you would want to use an ArrayList in place of a standard array. An ArrayList is essentially a dynamic array that grows and shrinks as necessary to contain the elements you store in it. This will get rid of your problem with null values, since this will prevent you from having any unused elements in your array.
Replace
String[] flowerPack = new String[25];
with
ArrayList<String> flowerPack = new ArrayList<>();
If you wanted to add or remove a value from the ArrayList you could do
// Add value.
flowerPack.add(value);
// Remove value
flowerPack.remove(value);
If you want to access a certain element in the ArrayList:
String element = flowerPack.get(indexOfElement);
If you want to get the size of the ArrayList:
int size = flowerPack.size();
And if you don't want to modify your sorting method, you can keep it the same by replacing the line
sortFlowers(flowerPack);
with
sortFlowers(flowerPack.toArray(new String[0]));
For an overview of other ArrayList methods and properties, check the online documentation:
https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html
The error says that you are trying to deal with the array that holds a value of null. to understand better, fill in all 25 spots in the array and run the program, it will not give you any error.
Here is the solution that you need.
private void sortFlowers(String flowerPack[])
{
//get the length of the array by counting arrays where the value is not null.
int length = 0;
for (int i = 0; i < flowerPack.length; i++)
{
if (flowerPack[i] != null)
{
length = length + 1;
}
}
//just confirm that the count is correct.
System.out.println(length);
//set the length to the "length" variable as we have found above.
for(int i = 0; i < length; i++)
{
String currentMinFlow = flowerPack[i];
int minIndex = i;
for(int j = i; j < length;j++){
if(currentMinFlow.compareToIgnoreCase(flowerPack[j]) <0)
{
currentMinFlow = flowerPack[j];
minIndex = j;
}
}
if(minIndex != i){
flowerPack[minIndex] = flowerPack[i];
flowerPack[i] = currentMinFlow;
}
}
}
Just replace your sortFlowers method with above code and check.

working around a null element in an array

In my program, i "deleted" an element by turning it into a null as you can't delete an element from an array so employee [i] = null. However, I was wondering, if I wanted to work with the array that had a null element, like add all the numbers in the array, how do I do this without any problems?
[UPDATE:]
My array contains the first names, last names and ages of 4 employees, I've "deleted" one of the employees details by making it null. As per all of the suggestions I got, I tried to add all the ages using:
int sum = 0;
for (int i = 0; i < employee.length; i++) {
if (employee[i] != null)
sum += employee[i].getAge();
}
but all I get is that sum = 1.
If the only operation you're going to perform on your array is the sum of all elements, it would make more sense to set the deleted elements to 0 instead of null. This way, you will not need the extra null check on every iteration.
You have to check if that element is null or not. If it is, add to the sum. If not, do nothing.
int sum = 0;
for (int i = 0; i < employee.length; i++) {
if (employee[i] != null)
sum += employee[i];
}
public int addAllNums(int[] nums)
{
int sum=0;
for(int i=0;i<nums.length;i++)
{
if(nums[i]!=null)sum+=nums[i];
}
}
You just have to iterate over your array and check if the current employee is not null :
int sum = 0;
for(int i = 0; i < employee.length; i++) {
if(employee[i] != null) {
sum += employe[i].getNumber();
}
}

Count The Amount Of Data In An Array Including SOME Null

I'm coding in java and I need to create a function that returns the number of data objects that are currently in an ArrayList. At the moment I have this:
int count = 0;
for (int i = 0; i < data.length; i++)
{
if (data[i] != null)
{
count ++;
}
}
return count;
But the problem is that an array list that includes null data is acceptable, and I have to count their null data towards this counter. How do I include the null data that's in the middle of this array, and not the null data that's not supposed to be counted for?
For example, I have some tester code that adds (8),null,null,(23),(25) to the array, and this function should return 5 when the initial array size is 10.
I'm going to assume you're using a regular array (your question is somewhat ambiguous about this). Traverse through the array backwards until you find a non-null element:
public static int count(Object[] a) {
int i = a.length - 1;
for (; i >= 0 ; i--)
if (a[i] != null)
break;
return i + 1;
}
You could also have
public static <T> int count(T[] a) {
int i = a.length - 1;
for (; i >= 0 ; i--)
if (a[i] != null)
break;
return i + 1;
}
Let's test it out, using an example analogous to the one you provided:
Object[] a = new Object[10];
a[0] = new Object();
a[3] = new Object();
a[4] = new Object();
System.out.println(count(a));
Output:
5
You will need two separate counters. The first one will count normally. The second one starts counting when you find null data. Then when you find a non-null data, just add the second counter to the first one and continue counting with the first counter until you find a null again.
int count = 0;
for (int i = data.length - 1; i >= 0; i--)
if (data[i] != null || count > 0)
count += 1;
return count;
At least that's how I understood your requirements - count nulls, except for trailing nulls.
But maybe that's not actually what you meant?
Edit
Unless you're actually using ArrayList (as Jon was asking), where .size() is different from capacity and will count all added elements (including nulls). You can't actually even get the capacity from an ArrayList.

First Element in TwoDimensional Array goes to null?

I am using this code to insert the details in to TwoDimensional Array. But while retrieving the data from the array the first element value changes to null.
Cursor consultancy = db.getConsultancy(this);
if(consultancy!=null)
{
consultancy.moveToFirst();
consultancy.moveToNext();
consultancynames = new String[(int) db.getConsultancyCount()-1];
for(int i=0;i<db.getConsultancyCount()-1;i++)
{
consultancynames[i] = consultancy.getString(2);
int consultantid = Integer.parseInt(consultancy.getString(consultancy.getColumnIndex(TimeAndExpensesLocalDB.CT_CONSULTANCYID)));
Cursor project_namecur = db.getProjectCode(this, consultantid);
if(project_namecur!=null)
{
project_namecur.moveToFirst();
projectname = new String[(int) db.getConsultancyCount()][project_namecur.getCount()];
for(int j=0;j<project_namecur.getCount();j++)
{
projectname[i][j] = project_namecur.getString(3);
project_namecur.moveToNext();
}
}
consultancy.moveToNext();
}
}
//... Print array
for (int i =0; i < consultancynames.length; i++) {
for (int j = 0; j < projectname.length; j++) {
System.out.print(" " + projectname[i][j]);
}
System.out.println("");
}
Output
05-25 12:58:22.700: I/System.out(2373): null null null
05-25 12:58:22.700: I/System.out(2373): Other-1 Other-2 Other-3
I am not sure what is happening.
Thanks for your help guys..
You're creating a new array on each iteration of the loop:
projectname = new String[(int) db.getConsultancyCount()][project_namecur.getCount()];
So on the first iteration you're creating an array and filling in the first "row" of the array. On the second iteration you're creating a new array (which will default to having null elements) and filling in the second row.
I suspect you need to allocate the "outer" array once before the loop, then allocate the "inner" array based on how many project names there are for that consultant:
// Note: more idiomatic names would be consultancyNames and
// projectNames. It's also unclear why you're subtracting one from the count...
consultancynames = new String[(int) db.getConsultancyCount() - 1];
projectnames = new String[consultancynames.length][];
for (int i = 0;i< consultancenames.length; i++) {
...
projectnames[i] = new String[project_namecur.getCount())];
...
}
Then you'll need to change your display code too, e.g. to
for (int i =0; i < projectname.length; i++) {
for (int j = 0; j < projectname[i].length; j++) {
System.out.print(" " + projectname[i][j]);
}
System.out.println("");
}
Note that you can't do the following:
projectname = new String[(int) db.getConsultancyCount()][project_namecur.getCount()];
for(int j=0;j<project_namecur.getCount();j++)
{
projectname[i][j] = project_namecur.getString(3);
project_namecur.moveToNext();
}
Here's why:
After the first line projectname will be an array of arrays.
Since the arrays are object references you have an array of object references.
Since the default value of an object reference is null, you'll have an array of null elements.
This means you can't do
projectname[i][j] = project_namecur.getString(3);
since it corresponds to
String[] row = projectname[i];
// row == null !
row[j] = project_namecur.getString(3);

Categories