Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-5017904

(coll) Collections.emptyIterator, Collections.emptyEnumeration

XMLWordPrintable

    • b18
    • generic, x86
    • generic, linux
    • Not verified

        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)
        ======================================================================

              martin Martin Buchholz
              gmanwanisunw Girish Manwani (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: