How to check if Iterator.next() is == null? - java

How do I check if the next element in the list is null ?
while(it.hasNext()){
System.out.println(it.next()+"\n");
}
this is how I tried, but when the last element is null it prints it as null.
I tried to change it
while(it.hasNext()){
if(it.next()==null){
}else
System.out.println(it.next()+"\n");
}
but this just makes it worst because some of the elements don't even print!
This is my Iteration method/anonymous class
public Iterator<Filmi> iterator3DFilms ()throws FilmiException{
if(filmList.isEmpty())
throw new FilmiException("No Films on the list");
return new Iterator<Filmi>(){
private int index=0;
public boolean hasNext(){
return index <filmList.size();
}
public Filmi next(){
Filmi lb = filmList.get(index++);
if(lb.is3D()== true)
return lb;
if(hasNext())
return next();
return null;
}
public void remove(){}
};
}
The null print only happens at the last element
Thank you.

Naturally, code like
if (it.next() == null){
} else {
System.out.println(it.next()+"\n");
}
will consume every other non-null element, as you are observing. Plus calling it.next() without checking it.hasNext() is a recipe for disaster.
Why not write
Foo/*ToDo - use the correct type here*/ foo = it.next()
if (foo != null){
/*ToDo*/
}
instead?

No it cannot work this way because if it.next() is not null you call it.next() twice which will make you skip a value that could not even be available.
Use a variable instead as next:
Object o = it.next();
if (o != null) {
...
}

you should use stream instead of iterator.
filmList.stream().filter(film->film!=null).filter(film->film.is3D())
Edit:
or, if you'r not in Java 8 :
Predicate<Film> isNotNullAnd3D = new Predicate<Person>() {
public boolean apply(Film f) {
return f != null && f.is3D();
}
};
Collection2.filter(filmList, isNotNullAnd3D)

You never mentioned why you use iterators explicitly in the first place.
Why not use implicit iterator notation like this ? :
for (Film film : filmList) {
if (film != null ){
....
}
}

Additionally to what others said: in case you are doing a for-each loop with a primitive type like int
for (int node : input) {
doSomething(node);
}
you might want to consider using the Wrapper class instead:
for (Integer node : input) {
if (node == null) throw new IllegalArgumentException();
doSomething(node);
}

Related

Java use instanceof with iterator

I have an abstract class Usuarioand an ArrayList<Usuario> with objects of its three subclasses. I now want to iterate through the ArrayList and return a value depending of the result of using instanceof against that object.
I get an error: java.util.NoSuchElementException.
I suppose it is because of the iterator being an object of Iterator and not from any of the subclasses from Usuario. Am I right? is there any solution for that?
public int comprobarDni(String dniAComprobar, ArrayList<Usuario> listaUsuarios) {
Iterator<Usuario> itUsuarios = listaUsuarios.iterator();
while (itUsuarios.hasNext()) {
if (dniAComprobar.equals(itUsuarios.next().getDni())) {
if (itUsuarios.next() instanceof UsuarioBiblioteca) {
return 1;
} else if (itUsuarios.next() instanceof Bibliotecario) {
return 2;
} else if (itUsuarios.next() instanceof BibliotecaExterna) {
return 3;
}
}
}
return 0;
}
Iterator.next() returns the next item and advances the cursor. That's not what you want so try this instead:
Usuario usuario = itUsuarios.next();
...
if (usuario instanceof UsuarioBiblioteca) {
return 1;
} else if (usuario instanceof Bibliotecario) {
return 2;
} else if (usuario instanceof BibliotecaExterna) {
return 3;
}
With your code consider the following case: listaUsuarios only contains two elements of type BibliotecaExterna. Your first call to next() will return the first element but since the type doesn't match you issue the second call to next() which returns the second element. Again the type doesn't match so you issue a third call to next() (itUsuarios.next() instanceof BibliotecaExterna) but there is no third element and hence you'll get the NoSuchElementException.
You are invoking itUsuarios.next multiple times during your iteration.
Therefore you might end up invoking it while the List has already been iterated fully, which will throw java.util.NoSuchElementException.
Consider assigning a Usuario value once, and referring to that instead:
while (itUsuarios.hasNext()) {
// reference this instead of itUsuarios.nex() for next references
Usuario usuario = itUsuarios.next();
Or...
Go with fast enumeration for cleaner looking code:
for (Usuario usuario: listaUsuarios) {
...
There is a huge misconception in your code:
If your current element is an instance of BibliotecaExterna it will call next() in the first if-statement and check it against UsuarioBiblioteca. But then the element has already changed.
Instead store it at the beginning:
Usuario element = itUsuarios.next();
if(element instance of ...)
...

Adding a object to a linked list at the end but always resulting into an error when a 2nd object is passed thru

I'm working on this method with linked list.
It's a method that add's an object at the end of the list.
I've got a problem when adding a second object in the linked list.
It gives me a NullPointerException at the while :
while (this.actual.getNext() != null)
I can't see what's wrong and i've been on this for an hour doing junits tests.
Any help ?
here's the complete code :
public boolean addEnd(T element) {
boolean res = false;
this.actual = this.head;
if (element != null) {
if (this.actual == null) {
this.head= new Node<T>(element);
res = true;
nbElm++;
} else if (!hasElement(element)) {
while (this.actual.getNext() != null) { //Gives me an error NullPointeException
this.actual = this.actual.getNext();
}
Node<T> next = new Node<T>(element);
this.actual.setNext(next);
res = true;
nbElm++;
}
}
return res;
}
Looking at this addEnd method, I think this.actual has no reason of being an instance variable. It should be a local variable of the method. Being an instance variable may cause other methods that use it to interfere with addEnd. I'm guessing hasElement modifies this variable, causing this.actual to become null before the start of your while loop.

Check if element in object is null

I have a simple dataset class similar to:
class DataSet {
private String value;
private String additionalValue;
public DataSet(String value, String additionalValue) {
this.value = value;
this.additionalValue = additionalValue;
}
public String getAdditionalValue() {
return this.additionalValue;
}
}
Then I have created an ArrayList<DataSet> and added a new element DataSet("Value1", null).
Now at some point I need to check if the entry with value "Value1" has additionalValue and if it does, what it is.
I do a simple loop checking if value.equals("Value1") == true, then I do:
if (element.getAdditionalValue() != null) {
return element.getAdditionalValue();
}
However, as soon as it gets to the if statement, it throws an error saying that the value is null.
How can I make it so that it doesn't throw an error and just skips the return statement if additionalValue is null?
EDIT:
But the thing is that the element cannot be null at the point where it checks additionalValue as it passed through the element.getValue.equals("Value1") condition.
for (DataSet element : dataSet) {
if (element.getValue.equals("Value1")) {
if (element.getAdditionalValue() != null) {
return element.getAdditionalValue();
}
}
}
I think the problem is that your element object is null, so you have to check it before checking additionalValue.
if (element != null && element.getAdditionalValue() != null){
return element.getAdditionalValue();
}
This will sort you out:
if (element != null && element.getAdditionalValue() != null) {
return element.getAdditionalValue();
}

check if an object is null

I have a linked list in which first node contains null object. means firstNode.data is equal to null, firstNode.nextPointer = null, firstNode.previousPointer = null.
And I want to check if firstNode is null or not.
So I tried-
if(list.firstNode == null){
//do stuff
}
but this doesn't works?
I also tried equals too. Any suggestions?
I tried printing. And I got as-
{null} -- firstNode
I think your firstNode is not null, but its fields are. Try something like this:
if (list.firstNode.data == null) {
//do stuff
}
Did you try
if (list.firstNode.data == null) { /* Do stuff */ }
You checking for list.firstNode being null. Do you mean to check for
list.firstNode.data==null
The answer is in the question. You said:
have a linked list in which first node contains null object. **means firstNode.data is equal to null**,
This means you should do the following instead:
if(list.firstNode.data == null){
//do stuff
}
It seems to me that your question is related to the processing of a doubly-linked list.
To check if empty use: (list.firstNode.next == list.firstNode.previous) this is true for an empty doubly linked list.
You can check if all the fields of the node are null:
Node firstNode = list.firstNode;
if(firstNode.data == null &&
firstNode.nextPointer == null &&
firstNode.previousPointer == null) {
//Do stuff
}
Or to prevent code repetition, you can either create an instance method isNull() to do the test or create a NULL object and override the equals method in your Node class to check if a node is equal to the null node as you described.
class Node<E> {
//The null node, assuming your constructor takes all three values.
public static final Node NULL = new Node(null, null, null);
//Fields here with constructors etc.
#Override
public void equals(Object obj) {
if(!obj instanceof Node) return false;
Node<?> node = (Node<?>)obj;
if(node.data.equals(this.data) &&
node.nextPointer == this.nextPointer &&
node.previousPointer == this.previousPointer) {
return true;
} else {
return false;
}
}
Then when you want to check if a node is null you can do:
if(list.firstNode.equals(Node.NULL)) {
//Do stuff
}

How to avoid null pointer error

I trying to find whether the elements of 2 arrayLists are match or not.
But this code give me error Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException since some of the elements are null.
How can I solved this problem?
String level []={"High","High","High","High","High","High"};
ArrayList<Object> n = new ArrayList<Object>(Arrays.asList(level));
String choice []={null,"High","Low","High",null,"Medium"};
ArrayList<Object> m = new ArrayList<Object>(Arrays.asList(choice));
//Check if the two arrayList are identical
for(int i=0; i<m.size(); i++){
if(!(m.get(i).equals(n.get(i)))){
result= true;
break;
}
}
return result;
}
Just use Arrays.equals, like so:
String level []={"High","High","High","High","High","High"};
String choice []={null,"High","Low","High",null,"Medium"};
return Arrays.equals(level, choice);
The problem is that you are calling the equals method on some elements without first checking for null.
Change to:
for(int i=0; i<m.size(); i++){
if(m.get(i) != null && !(m.get(i).equals(n.get(i)))){
result = true;
break;
}
}
Or if you want to allow two null values to compare equal:
for(int i=0; i<m.size(); i++){
if (m.get(i) == null) {
if (n.get(i) != null) {
result = true;
}
} else if(!(m.get(i).equals(n.get(i)))){
result = true;
}
if (result) {
break;
}
}
One thing I don't get - why are you setting result to true when you find a mismatch? Don't you want to return true if both lists match and false otherwise?
The root of this problem could be you are using null as an actual value.
Just looking at your code you could use enum and instead of null use an EMPTY value. Then you can actually compare with in a list without nullpointerexceptions.
Check this out:
http://java.sun.com/docs/books/tutorial/java/javaOO/enum.html
Also try to avoid using arrays. Just use List but use the proper type. Don't use List<Object> that is almost never valid.
null should indicate an error or testing only. It should never be used in valid code as you will create null pointer exception bugs during runtime.
if you know the first list never contains nulls switch the call around
if(!(n.get(i).equals(m.get(i)))){
also specifying ArrayList<Object> is bad practice, use List<String> if it is actually String objects.
Check if the objects are the same object (or both null) first. Check for null before you do the equals() test.
boolean result = true;
String level[] = { "High", "High", "High", "High", "High", "High" };
ArrayList<String> n = new ArrayList<String>(Arrays.asList(level));
String choice[] = { null, "High", "Low", "High", null, "Medium" };
ArrayList<String> m = new ArrayList<String>(Arrays.asList(choice));
// Check if the two arrayList are identical
for (int i = 0; i < m.size(); i++) {
String mElement = m.get(i);
String nElement = n.get(i);
if (mElement == nElement) {
result = true;
} else if ((mElement == null) || (nElement == null)) {
result = false;
break;
} else if (!(m.get(i).equals(n.get(i)))) {
result = false;
break;
}
}
return result;
}
Rewrite your if like this in order to check for both double-nullity and single-nullity:
if((m.get(i) == null && n.get(i) == null) || (m.get(i) != null && !(m.get(i).equals(n.get(i)))))
Rather than solving this specific problem, give yourself a tool you can use over and again, e.g.:
public static final boolean areEqual(Object o1, Object o2) {
return o1 == null ? o2 == null : o1.equals(o2);
}
...in some handy utility class, then use that in your loop.
But of course, for this specific requirement, derivation has the right answer (use java.util.Arrays.equals(Object[],Object[])).
Remove NULLs
You can remove NULL values from your List objects before processing.
myList.removeAll( Collections.singleton( null ) );
The Collections class is a bunch of convenient utility methods. Not to be confused with Collection (singular), the interface that parents List and is implemented by ArrayList.
See this posting, Removing all nulls from a List in Java, for more discussion.

Categories