Linked List Null Error - java

I have written the following code to compute the sum of all the even entries in a LinkedList. However, I keep getting a NullPointerException because of the line where I use (n.getNext).getNext().
Could any of guys tell me as to why this is happening?
Here is the piece of code I'm referring to:
public int sumEven() {
return sumEven(head);
}
// private sumEven helper
private int sumEven(IntListNode n) {
int nodeNumber=1;
int count=0;
if(n.getNext() == null && nodeNumber%2 == 0) {
return n.getValue();
} else if((n.getNext()).getNext() == null && nodeNumber%2 == 0) {
return n.getValue();
} else {
nodeNumber++;
if(nodeNumber%2 == 0) {
count+=n.getValue();
return count+ sumEven(n.getNext());
} else {
return count + sumEven(n.getNext());
}
}
}

Because what if: In the first if statement n.getNext() is null but nodeNumber%2 is not equal to 0
So you go to the next if statement which says n.getNext().getNext() == null where already the first getNext() is null since it passed the first part of the previous if statement but failed the if statement because of the nodeNumber%2 == 0 part.
Ex: nodeNumber = 1 and n.getNext() = null
First if(true && false) => false
Second if(ERROR) Cuz the previous if statement has the first part true which says n.getNext() is null

There are many problems in the code. How about rethink the strategy? If you want to make it recursive, you can assume that the private method sumEven() will always be called with an even node. Then all that private method does is add up whatever that it is called with.
The following code is not tested but shows what I mean.
public int sumEven() {
return sumEven(head,0);
}
private int sumEven(IntListNode n, int total) {
if(n==null) return total;
total += n.getValue(); // sums up running total
if(n.getNext()==null) return total;
return sumEven(n.getNext().getNext(),total); // calls next even node with current running total
}

Related

How can I check if two lists are equals?

I have to solve one problem, I don't know the reason why my code doesn't work.
I have to check if two lists I created are completely equals so they have the same value at the same position.
I'm allowed to use loops as well, even by I prefer the recursive mode.
Thank you so much for your help and time!
public static boolean checkEquality(Node n, Node m) {
if(n != null && m != null) {
boolean res = false;
while(n!=null) {
if(n.getElem()==m.getElem()) {
n = n.getNext();
m = m.getNext();
res = true;
}
else
{
res = false;
}
}
return res;
}
else
{
System.out.println("Lists empty!");
return true;
}
}
There are a couple of weak spots, so I give the solid solution:
public static boolean checkEquality(Node n, Node m) {
while (n != null && m != null) {
//if (!Objects.equals(n.getElem(), m.getElem())) {
if (n.getElem() != m.getElem()) {
return false;
}
n = n.getNext();
m = m.getNext();
}
return n == null && m == null;
}
Comparing can only be done while both n and m are not null. Your code only checks n.
== is not valid for instance for String. Instead of .equals one might also use Objects.equals which also tests for null.
getNext in every loop step.
two empty lists are also equal. Both lists should end at the same time.
The tst fails as soon as two compared nodes are not equal. So one should start with assuming a true result. And as soon as the comparison fails, one should no longer loop and certainly not overwrite res from false to true.
it would help if you elaborate what type of list u are comparing,
linkedlist or arrays. based on your function, it seems that you are planning to compare a linkedlist.
linkedlist documentation
arrays documentation
// sample comparison
boolean areIdentical(Node a_head, Node b_head) {
Node a = a_head, b = b_head;
while (a != null && b != null) {
if (a.data != b.data)
return false;
/* If we reach here, then a and b are not null
and their data is same, so move to next nodes
in both lists */
a = a.next;
b = b.next;
}
// If linked lists are identical, then 'a' and 'b'
// must be null at this point.
return (a == null && b == null);
}

How to use a "Do While" loop to iterate through a list

public static boolean hasGreaterDoWhile(List<Integer> numbers, int number) {
int d = 0;
do {
if (numbers.get(d) > number){
return true;
}
d++;
}
while (d < numbers.size());
return false;
}
(JAVA only)
P.s This is a function i have tried, in order to check the first argument, and if it contains a number that is larger than the second argument, it will then return true, and flase otherwise.
Note that it is using do while loop. I just don't know which part of this code i have done wrong, because the system keeps telling me that "java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0".
Thank u, any hint will be much appriciated.
your list of Integers is empty. you can't access an index of an empty list:
public static boolean hasGreaterDoWhile(List<Integer> numbers, int number) {
int d = 0;
if (numbers.isEmpty()) return false;
do {
if (numbers.get(d) > number){
return true;
}
d++;
}
while (d < numbers.size());
return false;
}
A do-while control block works as follows:
Execute the do block
Check the condition. If it holds, return to (1)
Notice the order of this flow. Unlike a standard while, do-while will always execute one iteration before checking the condition. Therefore, for an empty list you will always try to access the 0-index element of the table, which does not exist, hence the error. You can use a while loop to avoid this:
public static boolean hasGreaterDoWhile(List<Integer> numbers, int number) {
int d = 0;
while (d < numbers.size()) {
if (numbers.get(d) > number){
return true;
}
d++;
}
return false;
}
You should check whether the collection is empty
like this
if(numbers == null || numbers.isEmpty()) {
return false;
}
int d = 0;
do {
if (numbers.get(d) > number){
return true;
}
d++;
}
while (d < numbers.size());
return false;

Java beginner exercise with methods

I am real beginner in Java and I have one simple exercise where I need to convert m/h into km/h using a method and a return from it.
I have to define 2 situations: if km/h < 0 return -1 (error) and if km/h > 0 return km/h * 1.609 (value in m/h).
I tried everything I could think of but I either get a no return statement error or no output when I try to run it.
I can't understand why even if I gave it more than one return option it just doesn't work whatever the value is. I could use System.outprintln or String but the exercise specify I must use a return method.
here is my code, written in IntelliJ:
package EXERCISE;
public class Main {
public static void main(String[] args) {
toMilesPerHour(0);
}
public static double toMilesPerHour(double kilometersPerHour) {
if (kilometersPerHour < 0) {
return -1;
}
else if (kilometersPerHour > 0) {
return kilometersPerHour * 1.609d;
}
else if (kilometersPerHour == 0) {
return 0;
}
return kilometersPerHour * 1.609;
// if I don't write return here it gives me no return statement error,
// if I write it, it gives me no output with value > or < 0 but no error.
}
}
public static double toMilesPerHour(double kilometersPerHour) {
if (kilometersPerHour < 0) {
return -1;
}
else {
return kilometersPerHour * 1.609;
}
}
Try it like this:
public static double toMilesPerHour(double kilometersPerHour) {
return (kilometersPerHour > 0 ? kilometersPerHour*1.609 : -1;
}
You could also throw an exception if speed is negative:
public static double toMilesPerHour(double kilometersPerHour) {
if (kilometersPerHour < 0) throw new IllegalArgumentException("speed cannot be negative");
return kilometersPerHour*1.609;
}
Even if you use a method, you have to print the returned value:
package EXERCISE;
public class Main {
public static void main(String[] args) {
System.out.println(toMilesPerHour(0));
}
public static double toMilesPerHour(double kilometersPerHour) {
if (kilometersPerHour < 0) {
return -1;
}
else if (kilometersPerHour > 0) {
return kilometersPerHour * 1.609d;
}
else if (kilometersPerHour == 0) {
return 0;
}
return kilometersPerHour * 1.609;
//if I don't write return here it gives me no return statement error,
//if I write it, it gives me no output with value > or < 0 but no error.
}
}
Furthermore, you can get rid of the return statement at the end:
public static double toMilesPerHour(double kilometersPerHour) {
if (kilometersPerHour < 0) {
return -1;
}
else {
// you don't need to check if kilometersPerHour is 0, since every number multiplied with 0 is 0
return kilometersPerHour * 1.609;
}
}
If you use if()... else you have exactly two options. Either you go into the if clause and do whats there, or you go into the else clause. If if-clause and else-clause both have a return-statement, everything goes fine.
But you don't have if-else-clauses! You have if-else-if-clauses!
If the if-clause doesn't hold, you go into the else-clause, which again has an if-clause and so on. Finally you don't have a default else clause.... if you don't get into the first if-clause, you check in the else-clause, if the condition holds. If not, you check the condition in the next else clause. The last return-statement finally is the default else clause. We all, as humans, see, that every condition (<, == >) is covered, but the compiler doesn't see that!
The reason compiler gives you "no return statement" error is because you didn't cover all possible cases with your ifs: there is Double.NaN, which is not equal to 0 (or any other value, for that matter, including itself) and neither greater nor lesser than 0.
Also, compiler doesn't analyze your code deep enough to check if you covered all possible variants anyway: if you replace double with long, the result is the same - the compiler will see the reachable branch that doesn't return anything, and so it produces an error.
To fix an error, you need to have all branches return something:
if (kilometersPerHour < 0) {
return -1;
}
else if (kilometersPerHour == 0) {
return 0;
}
// Note: I don't have explicit check for NaN,
// because any arithmetic on NaN produces NaN,
// which would be the correct result for this function.
// So I let the "*" operator to check for NaN instead.
return kilometersPerHour * 1.609;

Recursion: Finding number of elements

I have following recursive method that returns the number of element in a nested Collection. A Collection contains child Collections plus Elements.
Is there a faster algorithm to achieve this?
int elementCount = 0;
#Override
public int getElementCount(CollectionDTO collectionDTO){
if(collectionDTO == null){
return elementCount;
}
if (collectionDTO.getChildCollectionDTOs() != null
&& collectionDTO.getChildCollectionDTOs().size() > 0) {
for (CollectionDTO collection : collectionDTO.getChildCollectionDTOs())
getElementCount(collection);
}
if(collectionDTO.elements != null && collectionDTO.elements.size() > 0)
elementCount +=collectionDTO.elements.size();
return elementCount;
}
In the worst case you are calling collectionDTO.getChildCollectionDTOs() three times so you should consider to call it just once, store the result in a variable and reuse it.
If another caller of this method which has the same reference to this object comes into play the usage of that class level variable elementCount will have side effects and won't return the correct result.
You should always use braces {} although they are optional for single lined if statements or for loops. This will just make your code less error prone.
Applying these points will lead to
#Override
public int getElementCount(CollectionDTO collectionDTO){
if(collectionDTO == null){
return 0;
}
int elementCount = 0;
if(collectionDTO.elements != null && collectionDTO.elements.size() > 0) {
elementCount +=collectionDTO.elements.size();
}
List<CollectionDTO> children = collectionDTO.getChildCollectionDTOs();
if (children == null){
return elementCount;
}
for (CollectionDTO collection : children)
elementCount += getElementCount(collection);
}
return elementCount;
}

Methods that return boolean values

Okay, so my question is regarding boolean returns. For my Comp Sci homework, I have to make a course registration program using methods, and one of them is an add course method. Basically, you search for the class in a catalog, and if it matches you add it to the students schedule and return a boolean value of true. I did this, but for some reason it is giving me an error. Here is the code:
public static boolean addCourse(
Course[] catalog,
Course[] mySchedule,
int myNumCourses,
int dept,
int courseNum)
{
int j;
int i;
int k;
int deptCat;
int courseNumCat;
Course courseAdd = null;
char checkDay;
int checkTime;
if (mySchedule.length == myNumCourses) {
return false;
}
for (i = 0 ; i < catalog.length ; i++) {
Course course = catalog[i];
deptCat = course.getDepartment();
courseNumCat = course.getCourseNumber();
if (deptCat == dept && courseNumCat == courseNum) {
courseAdd = catalog[i];
break;
}
else continue; }
for (j = 0 ; j < myNumCourses ; j++) {
if (mySchedule[j] == null) {
mySchedule[j] = courseAdd;
return true;
}
else continue;
}
for (k = 0 ; k < mySchedule.length ; k++) {
Course course = mySchedule[k];
if (course != null) {
checkDay = course.getDay();
checkTime = course.getPeriod();
if (checkDay == courseAdd.getDay() && checkTime == courseAdd.getPeriod()) {
return false;
}
}
else continue;
}
}
Why doesn't it recognize the boolean return values? Is it because I placed them inside a loop?
You need to place a return-statement at the end of your method, even if you might know it will never be reached (the compiler is not smart enough to know that, which explains the error).
For instance, even this will not compile:
public static boolean foo() {
if (true)
return true;
}
unless we add a final return statement. What you have is analogous.
There is nothing wrong with putting your return values in loops, however, the compiler sees no guarantee that this method will return a value and thus raises an error. At the very end of the method you need to return either true or false, whichever is most appropriate. All of your returns are within conditionals and therefor could fail to execute leaving your function with no return statement.
You must explicitly return a boolean(true/false) in ALL code path.Because your function's return type is "boolean".
In your case,you must add a return statement after the last loop.
If you don't want to write to many "return xx" statement,you can change the return type of this function to "void".And throw Exception in the false cases.
I think there is a problem with the last loop. If the condition for returning false is never met, it continues until it get to the end of the schedule, without returning anything. If you were to add a return at the end of the method this loop could fall through to it. Did you mean to return true after the loop, if no 'return false' is executed?
for (k = 0; k < mySchedule.length; k++) {
Course course = mySchedule[k];
if (course != null) {
checkDay = course.getDay();
checkTime = course.getPeriod();
if (checkDay == courseAdd.getDay()
&& checkTime == courseAdd.getPeriod()) {
return false;
}
} else
continue;
}
Where ever you are using if statement its possible else also must return or flow must go to another return.ELSE is missing with return.

Categories

Resources