-
Enhancement
-
Resolution: Fixed
-
P3
-
5.0, 6
-
b18
-
generic, x86
-
generic, linux
-
Not verified
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2152538 | OpenJDK6 | Martin Buchholz | P3 | Resolved | Fixed | b01 |
Name: gm110360 Date: 03/22/2004
A DESCRIPTION OF THE REQUEST :
In the Collections class, provide
public class Collections {
public final static Iterator EMPTY_ITERATOR = new EmptyIterator();
private final static EmptyIterator implements Iterator {
public boolean hasNext() { return false; }
public Object next() { throw new NoSuchElementException(); }
public void remove() { throw new UnsupportedOperationException(); }
}
// ..
}
Make Collections.EMPTY_LIST.iterator() and Collections.EMPTY_SET.iterator()
return Collections.EMPTY_ITERATOR
JUSTIFICATION :
Performance.
EMPTY_LIST and EMPTY_SET are stateless.
So is the iterator returned from them.
The current implementation, however, returns a new object
every time the iterator() method is invoked.
Returning an empty Collection in lieu of null from a method
is a good programming idiom.
For example
Hr hr = ..
List employees = hr.getEmployees(Department.ENGR);
for (Iterator i = employees.iterator(); i.hasNext(); ) {
// ..
}
The code works because Hr.getEmployees(..) never returns
null: instead its contract says that it always returns a non-null,
unmodifiable List. When there are no employees to return the
Hr implementation returns Collections.EMPTY_LIST.
But if Hr.getEmployees(..) returns Collections.EMPTY_LIST,
there is no good reason to make the user pay a performance
penalty (the creation of a new object) for invoking iterator().
This fix would take care of Collections.EMPTY_MAP since
it in turn returns EMPTY_SET when either keySet() or
values() is invoked.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I don't expect any objects to be created when invoking
any method on Collections.EMPTY_SET, EMPTY_LIST
or EMPTY_MAP, or on any object returned by them.
ACTUAL -
A new object is created every time iterator() is invoked
on any of the above.
CUSTOMER SUBMITTED WORKAROUND :
In order to avoid the performance penalty the user has
to check the size of the List. Continuing the above example,
Hr hr = ..
List employees = hr.getEmployees(Department.ENGR);
if ( !empoyees.isEmpty() ) {
for (Iterator i = employees.iterator(); i.hasNext(); ) {
// ..
}
}
This is as bad as allowing the Hr class return null and making
the user do something like
Hr hr = ..
List employees = hr.getEmployees(Department.ENGR);
if ( employees != null && !empoyees.isEmpty() ) {
for (Iterator i = employees.iterator(); i.hasNext(); ) {
// ..
}
}
(Incident Review ID: 244382)
======================================================================
A DESCRIPTION OF THE REQUEST :
In the Collections class, provide
public class Collections {
public final static Iterator EMPTY_ITERATOR = new EmptyIterator();
private final static EmptyIterator implements Iterator {
public boolean hasNext() { return false; }
public Object next() { throw new NoSuchElementException(); }
public void remove() { throw new UnsupportedOperationException(); }
}
// ..
}
Make Collections.EMPTY_LIST.iterator() and Collections.EMPTY_SET.iterator()
return Collections.EMPTY_ITERATOR
JUSTIFICATION :
Performance.
EMPTY_LIST and EMPTY_SET are stateless.
So is the iterator returned from them.
The current implementation, however, returns a new object
every time the iterator() method is invoked.
Returning an empty Collection in lieu of null from a method
is a good programming idiom.
For example
Hr hr = ..
List employees = hr.getEmployees(Department.ENGR);
for (Iterator i = employees.iterator(); i.hasNext(); ) {
// ..
}
The code works because Hr.getEmployees(..) never returns
null: instead its contract says that it always returns a non-null,
unmodifiable List. When there are no employees to return the
Hr implementation returns Collections.EMPTY_LIST.
But if Hr.getEmployees(..) returns Collections.EMPTY_LIST,
there is no good reason to make the user pay a performance
penalty (the creation of a new object) for invoking iterator().
This fix would take care of Collections.EMPTY_MAP since
it in turn returns EMPTY_SET when either keySet() or
values() is invoked.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I don't expect any objects to be created when invoking
any method on Collections.EMPTY_SET, EMPTY_LIST
or EMPTY_MAP, or on any object returned by them.
ACTUAL -
A new object is created every time iterator() is invoked
on any of the above.
CUSTOMER SUBMITTED WORKAROUND :
In order to avoid the performance penalty the user has
to check the size of the List. Continuing the above example,
Hr hr = ..
List employees = hr.getEmployees(Department.ENGR);
if ( !empoyees.isEmpty() ) {
for (Iterator i = employees.iterator(); i.hasNext(); ) {
// ..
}
}
This is as bad as allowing the Hr class return null and making
the user do something like
Hr hr = ..
List employees = hr.getEmployees(Department.ENGR);
if ( employees != null && !empoyees.isEmpty() ) {
for (Iterator i = employees.iterator(); i.hasNext(); ) {
// ..
}
}
(Incident Review ID: 244382)
======================================================================
- backported by
-
JDK-2152538 (coll) Collections.emptyIterator, Collections.emptyEnumeration
- Resolved
- duplicates
-
JDK-6356890 (coll) Collections.EmptyList could override iterator for improved performance
- Closed