In my previous post, I
explained why do we require empty collections. I recommend you to go through
the post "Why do we require empty collections?"
As you go through the
Collections class, you can come across following method definitions.
Method
|
Description
|
public static
<T> Enumeration<T> emptyEnumeration()
|
Returns an
enumeration that has no elements.
|
public static
<T> Iterator<T> emptyIterator()
|
Returns an iterator
that has no elements.
|
public static
<T> ListIterator<T> emptyListIterator()
|
Returns a list
iterator that has no elements.
|
Can you think for some
time, why do Collections class is providing the methods for empty iterators?
Ok let’s come to the
point, suppose you had an Employees class, where it is maintaining all your
employees information of your company. Your classes looks like below.
public class Employee { private int id; private String name; public Employee(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
import java.util.Arrays; import java.util.Iterator; import java.util.List; public class Employees { private List<Employee> employees; public Employees() { } public Employees(Employee... emps) { employees = Arrays.asList(emps); } public void printEmployees() { for (Employee emp : employees) { System.out.println(emp); } } public Iterator<Employee> getIterator() { return employees.iterator(); } }
As you closely observe the Employees class, there
is a flaw in it. Suppose you created an instance of Employees class by using
default constructor.
Employees employees
= new Employees();
Above statement don't initialize the instance
variable 'employees', so it is null by default. When you call getIterator()
method on Employees instance you will end up in NullPointerException.
import java.util.Iterator; public class Test { public static void main(String args[]) { Employees emps = new Employees(); Iterator<Employee> employees = emps.getIterator(); } }
Run Test.java, you will
get following kind of output.
Exception in thread "main" java.lang.NullPointerException at test123.Employees.getIterator(Employees.java:25) at test123.Test.main(Test.java:10)
How to resolve the problem?
Check whether the
instance variable 'employees' is null or not. If it is null, return
emptyIterator, else return employees.iterator()
public Iterator<Employee> getIterator() { return (employees == null) ? Collections.emptyIterator() : employees.iterator(); }
Following is the
updated version of Employees class.
import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; public class Employees { private List<Employee> employees; public Employees() { } public Employees(Employee... emps) { employees = Arrays.asList(emps); } public void printEmployees() { for (Employee emp : employees) { System.out.println(emp); } } public Iterator<Employee> getIterator() { return (employees == null) ? Collections.emptyIterator() : employees.iterator(); } }
Re run Test.java, you won’t get any
NullPointerException. There is a saying like; it is always better to return an
empty collection/iterator instead of null. In these kind of scenarios, you can use empty iterators.
You may
like
No comments:
Post a Comment