ListIterator.next() returns null - java

my question is really, really simple, but everything I find online tells me I am doing it the right way - but I obviously misunderstood something.
I have a simple, simple Java ListIterator, which in a while-hasNext()-loop returns a null for next(). Here's the code with my comments on the debug state:
[...]
ListIterator<Role> rolesIterator = currentUser.getRoles().listIterator();
// rolesIterator is now: java.util.ArrayList$ListItr
while( rolesIterator.hasNext() ) {
Role roleObject = rolesIterator.next(); // extra step for debugging reasons
String role = roleObject.getName(); // NullPointerException - roleObject is null
[...]
In my thoughts, the loop should not be entered, if there is no next() object - that's why I check using hasNext(). What did I understand wrong, and what is the correct way?

There is a next element in the list, and this next element happens to be null. For example:
List<String> list = new ArrayList<>();
list.add("foo");
list.add(null);
list.add("bar");
The above list has 3 elements. The second one is null.
Fix the code that populates the list and make sure it doesn't add any null Role in the list, or check for null inside the loop to avoid NullPointerExceptions.

ListIterator documentation states that next():
Throws:
NoSuchElementException - if the iteration has no next element
Furthermore, you do the appropriate hasNext() check as the loop condition. So the obvious conclusion is that currentUser.getRoles() contains null elements. To fix [this part of] your code:
while( rolesIterator.hasNext() ) {
Role roleObject = rolesIterator.next();
if(roleObject != null)
{
String role = roleObject.getName();
[...]
}

I believe list can contain null values.
so the roleObject can be null.
I prefer the for loop approach (cleaner):
for (Role roleObject : currentUser.getRoles()) {
...
}

Related

If statement - Variable order for null safety

Assume I want to check if the first element from a list is equal to "YES" or "NO".
dummy_method(List<String> myList) {
if(myList.isEmpty()) {
return null;
}
String firstListValue = myList.get(0).getStringValue();
// Should I do this:
if ("YES".equalsIgnoreCase(firstListValue)) {
return firstListValue;
}
// OR this:
if (firstListValue.equalsIgnoreCase("YES")) {
return firstListValue;
}
// Do something else
}
In other words: Does the order of if A equals B versus if B equals A matter when I already have a null-check?
Yes. It matters.
You have only checked if the list is non-empty. If the first element in the list is null then you will get a NullPointerException at
firstListValue.equalsIgnoreCase("YES")
But, if you can ensure all the elements (or at least the first element) in the list are non-null, then both the statements are equivalent.
For null safety you can use your first if like this:
if ("YES".equalsIgnoreCase(firstListValue)) {
return firstListValue;
}
because "YES" is hardcoded string and won't be null. Where as in 2nd approach, whenever the list element is null, you will get NullPointerException.
This check will also throw NullPointerException if the list is null, so you can check both conditions
if(myList!=null && !myList.isEmpty())
And also need 'null' check for all values retrieved through 'get()' , because if list is empty or specified index is out of range 'get()' method will not throw 'NullpointerException', it will just return null

Check whether list object is null in java

I'm checking whether a List object is null or not using java. But I'm not sure whether it is the optimized way or not.
Here is my code:
List<String> listSCBPLNewErrMsgs= new ArrayList<String>(Arrays.asList(SCBPL_NEW_ERRORMESSAGES.split("\\$\\#")));
The above line itself throws null pointer exception.
if(listSCBPLNewErrMsgs != null) <Right way?>
This will get all the values from the config.
Now, tomorrow if I change the config entry, this should not throw an null pointer exception
The new operator in Java can never return null. Neither can String#split.
What you may want to check, however, is that the list is not empty:
if (listSCBPLNewErrMsgs.isEmpty()) {
// do something
}
If SCBPL_NEW_ERRORMESSAGES is null that code will still fail.
Assuming that SCBPL_NEW_ERRORMESSAGES has some value or is empty, the split will return an array of size 0 or more. Changing it to a list from an array will yield either an array with 0 or more elements.
Lastly, the copy constructor will copy the content and assign it to a new list. In all scenarios, unless there is a null pointer on SCBPL_NEW_ERRORMESSAGES, the returned list (listSCBPLNewErrMsgs) will never be null, at most it will be empty, which can be checked with the isEmpty() method call.
As per your comment, if you are getting a null pointer on that line, it should be due to the fact that SCBPL_NEW_ERRORMESSAGES is null.
Try this:
List<String> listSCBPLNewErrMsgs = null;
if(SCBPL_NEW_ERRORMESSAGES != null) {
listSCBPLNewErrMsgs= new ArrayList<String>(Arrays.asList(SCBPL_NEW_ERRORMESSAGES.split("\\$\\#")));
}
else {
listSCBPLNewErrMsgs = new ArrayList<>();
}
If you want to check whether it is null it is right way (even though it will never be null), however if you simply want to check if list is empty then you should use isEmpty() method:
if(listSCBPLNewErrMsgs.isEmpty()) {/**/}
From the looks if your code your listSCBPLNewErrMsgs object won't be null. Test if it is empty using the listSCBPLNewErrMsgs.isEmpty();
If SCBPL_NEW_ERRORMESSAGES is nulll that will throw a NPE exception indeed since you will be using the split method on null.
You can first check if that's not null:
if (SCBPL_NEW_ERRORMESSAGES != null) {
//Instantiate list
//Optional isEmpty check
}
You will first check if SCBPL_NEW_ERRORMESSAGES is not null
Then you can instantiate your list and perform an optional isEmpty check on the new list.
if(SCBPL_NEW_ERRORMESSAGES != null)
List<String> listSCBPLNewErrMsgs= new ArrayList<String>Arrays.asList(SCBPL_NEW_ERRORMESSAGES.split("\\$\\#")));
No Need of listSCBPLNewErrMsgs != null as everyone said
First you have to check SCBPL_NEW_ERRORMESSAGES is null or empty
if(!TextUtils.isEmpty(SCBPL_NEW_ERRORMESSAGES))
You have to check both whether the list is null/empty or not. So I prefer
if(listSCBPLNewErrMsgs != null && !listSCBPLNewErrMsgs.isEmpty()) {
}
You need to add null check for SCBPL_NEW_ERRORMESSAGES.
if (SCBPL_NEW_ERRORMESSAGES != null && !SCBPL_NEW_ERRORMESSAGES.isEmpty()) {
In your declaration, list can not be null as your are doing new ArrayList<String>.
So no need to worry about null pointer exception.
If you wish to check for empty list.
Then you can try isEmpty() method.
if (SCBPL_NEW_ERRORMESSAGES != null && !SCBPL_NEW_ERRORMESSAGES.isEmpty()) {
List<String> listSCBPLNewErrMsgs = new ArrayList<String>(Arrays.asList(SCBPL_NEW_ERRORMESSAGES.split("\\$\\#")));
if (!listSCBPLNewErrMsgs.isEmpty()) {
// Do something.
}
}

Updating method to remove loop

This is how I understand method getUser below :
Return a User object or null
Get a Set of users and assign them to userSer.
If the set is not empty begin iterating over the set but
return the first user within the set.
Here is the method :
private User getUser(UserDet arg)
{
Set<User> userSet = arg.getUsers(User.class);
if (CollectionUtils.isNotEmpty(userSet))
{
for (User user : userSet)
{
return user;
}
}
return null;
}
I think I could replace the method with this :
private User getUser(UserDet arg)
{
Set<User> userSet = arg.getUsers(User.class);
if (CollectionUtils.isNotEmpty(userSet))
{
return userSet.iterator().next();
}
else {
return null;
}
}
This new method removes the loop and just returns the first element in the set, same as original implemention. Is it correct?
Yes. Actually, it's pretty much almost the same thing, as a foreach loop is syntactic sugar for using an iterator from an Iterable.
Note, however, that you don't need the nonempty check in the first variant, since the loop won't iterate in the case of an empty set anyway.
yes both are same. in first implementation, control will return on first iteration of the loop from the function and consequently loop will end.
Yes it is correct, I'd even go for removing the CollectionUtils.isNotEmptySet and use the Iterator's hasNext method... If the set is guaranteed to be non-null.
It seems to be correct, but it will only make the method a bit easier to read, it will not optimize it in terms of performance. Still I think the change is good and you should do it.
Yes, it does pretty much the same, but if your spec says to start iterating then maybe you should - maybe this method will be extended in the future.
BTW: it is a good convention that your method has only one return statement (i.e. you can create a variable, which will be returned, assigned a null at the beginning and assign a user inside your loop)
Yes. Both the methods return the first element in the set. The first method seems to have been written for something else previously and changed then keeping the for loop intact.
In anycase, the second method that you're proposing won't give any significant performance benefit but should be a better way than the first one.
So in case, UserDet#getUsers(Class) never returns null (but an empty Set in case no user could be found), the shortest (and in my opinion most readable) form is:
private User getUser(UserDet arg) {
Set<User> userSet = arg.getUsers(User.class);
return userSet.isEmpty() ? null : userSet.iterator().next();
}
I would do this.
I won't run a loop and more over I'l add a null check.
private User getUser(UserDet arg) {
Set<User> userSet = arg.getUsers(User.class);
if (userSet != null && userSet.size() > 0) {
return userSet.iterator().next();
}
return null;
}

ArrayList remove error

I'm working on a project for school but i'm a little stuck right now
My problem is that i have an arrayList of Squares
Each Square has a value(from 0 to 100). Its starting value is 9999 so i can check if its is checked.
If a square is checked i want it to be removed from the arrayList.
So after a while there will be no Squares left.
there is a little bit of code where the first value is set so thats why i check if the value is 9999.
But i get an error. One that i havent seen before.
Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
Vak = Square
this is my code:
while (!vakken.isEmpty()) { // check if empty
Iterator itrVak = vakken.iterator();
while (itrVak.hasNext()) {
Vak vak = (Vak) itrVak.next(); // here is get the error
if (vak.getValue() != 9999) {// check if square value is 9999
Collection checkVakken = vak.getNeighbour().values();
Iterator itre = checkVakken.iterator();
while (itre.hasNext()) {
Vak nextVak = (Vak) itre.next();
if (nextVak != null) {
if (nextVak.getValue() == 9999) {
nextVak.setValue(vak.getValue() + 1); // set value by its neighbour
vakken.remove(vak);
checkvakken.add(vak);
}
}
}
} else {
vakken.remove(vak);
checkvakken.add(vak);
}
}
}
You are removing elements from the collection while you are iterating it. As the iterator may produce unpredictable results in this situation, it fails fast throwing the exception you encountered.
You may only alter a collection through the iterator's methods while traversing it. There should be remove method on the iterator itself, that removes the current element and keeps the iterator intact.
While iterating, you should use Iterator instance for removing object:
itre.remove();
You can try like this:
itre.remove();
ITERATOR never lets you modify when you are iterating.. you need to use loops instead.. this happens coz you are using the Iterator, same time other thread is modifying the list...

LinkedList Iteration Exception

I am struggling with this error. I feel its really simple but cannot understand why am getting the error.
I keep getting a NullPointerException when I iterate through values in my linked list.
Code Snippet:
private void updateBuyBook(LimitOrder im) {
LimitOrder lm = null;
Iterator itr = buyBook.entrySet().iterator();
boolean modify = false;
while (itr.hasNext() && !modify) {
Map.Entry pairs = (Map.Entry) itr.next();
if ((((LinkedList<IMessage>) pairs.getValue()).size() > 0)) {
LinkedList<ILimitOrder> orders = (LinkedList<ILimitOrder>) pairs
.getValue();
ListIterator listIterator = orders.listIterator();
while (listIterator.hasNext() && !modify) {
LimitOrder order = (LimitOrder) listIterator.next();
if (order.getOrderID().equalsIgnoreCase(im.getOrderID())) { // error at this line
lm = order;
addToBuyMap(im);
modify = true;
break;
}
}
if (modify = true) {
orders.remove(lm);
break;
}
}
}
}
Error is at this line:
Exception in thread "main" java.lang.NullPointerException
order.getOrderID().equalsIgnoreCase(im.getOrderID()));
Please help. Is my assignment wrong in any way???
Please help!!!
Thanks
Changing your code a bit will make it longer, but much easier to find the error... instead of doing:
if (order.getOrderID().equalsIgnoreCase(im.getOrderID())) {
Change it to:
String orderID = order.getOrderID();
String imOrderID = im.getOrderID();
if(orderID.equals(imOrderID()) {
Then you will know if order or im is null. If neither of those is null then the things that could be null are orderID and imOrderID. It is now a simple matter of finding out which one of those is null.
If it is order or im then the program will crash on the order.getOrderID() or im.getOrderID() lines.
If, instead it is orderID or imOrderID that is null, then it will crash on if(orderID.equals(imOrderID()) {. You can then use System.out.println (or something better, like a debugger) do easily find out what is wrong.
If neither of those should be null then I suggest adding something like:
if(orderID == null) { throw new IllegalStateException("orderID cannot be null"); }
if(imOrderID == null) { throw new IllegalStateException("imOrderID cannot be null"); }
and then track down how it got set to null to begin with.
My guess would be that you're passing in the null, into im. I'll need to see more of the code to be sure.
You never check to see if im is null. I suspect it is.
One first look, where is im instantiated? You can also try to debug in your IDE so as to see whats going on?
Either im is null or order.getOrderID() is returning null.
Doesn't look like im is ever declared / assigned. So
im.getOrderID()
is probably where the null pointer exception is generated.
-- Dan
Edit:
Missed that im is passed in as an argument. So that leaves a few possibilities (in order of likelihood):
im is null (ie. user called function with null parameter)
order.getOrderID() is returning null
order is null (ie. the list has nulls in it)
Edit2:
Your line
if (modify = true)
Is fundamentally wrong and will always evaluate to true (single equal is for assignment, == is for comparison.)
When simply checking if a flag boolean is true or false, it is best to use:
boolean flag = true;
if(flag)
{
// True block
}
else
{
// False block
}
It will be good if you could add a debug point before that line and see which variable is null. looking at the code the answer is 1. order is null 2. order.getOrderID() is null or 3. im is null

Categories

Resources