Java Tutorial/Collections/Enumeration Interface

Материал из Java эксперт
Перейти к: навигация, поиск

An enumeration that iterates over an array.

   <source lang="java">

/**

* 
* JFreeReport : a free Java reporting library
* 
*
* Project Info:  http://reporting.pentaho.org/
*
* (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
*
* This library is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* ------------
* ArrayEnumeration.java
* ------------
* (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
*/

import java.util.Enumeration; import java.util.NoSuchElementException; /**

* An enumeration that iterates over an array.
*
* @author Thomas Morgner
*/

public class ArrayEnumeration implements Enumeration {

 /** The base datasource. */
 private Object[] objectarray = null;
 /** The counter holds the current position inside the array. */
 private int counter = 0;
 /**
  * Creates a new enumeration for the given array.
  *
  * @param objectarray the array over which to iterate
  * @throws NullPointerException if the array is null.
  */
 public ArrayEnumeration(final Object[] objectarray)
 {
   if (objectarray == null)
   {
     throw new NullPointerException("The array must not be null.");
   }
   this.objectarray = objectarray;
 }
 /**
  * Returns true if this enumeration has at least one more Element.
  *
  * @return true, if there are more elements, false otherwise.
  */
 public boolean hasMoreElements()
 {
   return (counter < objectarray.length);
 }
 /**
  * Returns the next element in the Array.
  *
  * @return the next element in the array.
  * @throws  NoSuchElementException  if no more elements exist.
  */
 public Object nextElement()
 {
   if (counter >= objectarray.length)
   {
     throw new NoSuchElementException();
   }
   final Object retval = objectarray[counter];
   counter += 1;
   return retval;
 }

}</source>





Concatenates the content of two enumerations into one.

   <source lang="java">

/*

* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common
* Development and Distribution License("CDDL") (collectively, the
* "License"). You may not use this file except in compliance with the
* License. You can obtain a copy of the License at
* http://www.netbeans.org/cddl-gplv2.html
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
* specific language governing permissions and limitations under the
* License.  When distributing the software, include this License Header
* Notice in each file and include the License file at
* nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the
* License Header, with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* Contributor(s):
*
* The Original Software is NetBeans. The Initial Developer of the Original
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
* Microsystems, Inc. All Rights Reserved.
*
* If you wish your version of this file to be governed by only the CDDL
* or only the GPL Version 2, indicate your decision by adding
* "[Contributor] elects to include this software in this distribution
* under the [CDDL or GPL Version 2] license." If you do not indicate a
* single choice of license, a recipient has the option to distribute
* your version of this file under either the CDDL, the GPL Version 2 or
* to extend the choice of license to its licensees as provided above.
* However, if you add GPL Version 2 code and therefore, elected the GPL
* Version 2 license, then the option applies only if the new code is
* made subject to such option by the copyright holder.
*/

import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.Iterator; import java.util.NoSuchElementException;

/**

* @since 4.37
* @author Jaroslav Tulach
*/

public class Utils {

 /**
  * Concatenates the content of two enumerations into one.
  * Until the
  * end of en1 is reached its elements are being served.
  * As soon as the en1 has no more elements, the content
  * of en2 is being returned.
  *
  * @param en1 first enumeration
  * @param en2 second enumeration
  * @return enumeration
  */
 public static <T> Enumeration<T> concat(Enumeration<? extends T> en1, Enumeration<? extends T> en2) {
     ArrayList<Enumeration<? extends T>> two = new ArrayList<Enumeration<? extends T>>();
     two.add(en1);
     two.add(en2);
     return new SeqEn<T>(Collections.enumeration(two));
 }

} class SeqEn<T> extends Object implements Enumeration<T> {

 /** enumeration of Enumerations */
 private Enumeration<? extends Enumeration<? extends T>> en;
 /** current enumeration */
 private Enumeration<? extends T> current;
 /** is {@link #current} up-to-date and has more elements?
 * The combination current == null and
 * checked == true means there are no more elements
 * in this enumeration.
 */
 private boolean checked = false;
 /** Constructs new enumeration from already existing. The elements
 * of <CODE>en should be also enumerations. The resulting
 * enumeration contains elements of such enumerations.
 *
 * @param en enumeration of Enumerations that should be sequenced
 */
 public SeqEn(Enumeration<? extends Enumeration <? extends T>> en) {
     this.en = en;
 }
 /** Ensures that current enumeration is set. If there aren"t more
 * elements in the Enumerations, sets the field current to null.
 */
 private void ensureCurrent() {
     while ((current == null) || !current.hasMoreElements()) {
         if (en.hasMoreElements()) {
             current = en.nextElement();
         } else {
             // no next valid enumeration
             current = null;
             return;
         }
     }
 }
 /** @return true if we have more elements */
 public boolean hasMoreElements() {
     if (!checked) {
         ensureCurrent();
         checked = true;
     }
     return current != null;
 }
 /** @return next element
 * @exception NoSuchElementException if there is no next element
 */
 public T nextElement() {
     if (!checked) {
         ensureCurrent();
     }
     if (current != null) {
         checked = false;
         return current.nextElement();
     } else {
         checked = true;
         throw new java.util.NoSuchElementException();
     }
 }

}</source>





Creating Custom Enumerations

   <source lang="java">

import java.lang.reflect.Array; import java.util.Enumeration; class ArrayEnumeration implements Enumeration {

 private final int size;
 private int cursor;
 private final Object array;
 public ArrayEnumeration(Object obj) {
   Class type = obj.getClass();
   if (!type.isArray()) {
     throw new IllegalArgumentException("Invalid type: " + type);
   }
   size = Array.getLength(obj);
   array = obj;
 }
 public boolean hasMoreElements() {
   return (cursor < size);
 }
 public Object nextElement() {
   return Array.get(array, cursor++);
 }

} public class MainClass {

 public static void main(String args[]) {
   Object obj = new int[] { 2, 3, 5, 8, 13, 21 };
   Enumeration e = new ArrayEnumeration(obj);
   while (e.hasMoreElements()) {
     System.out.println(e.nextElement());
   }
   try {
     e = new ArrayEnumeration("Not an Array");
   } catch (IllegalArgumentException ex) {
     System.out.println(ex.getMessage());
   }
 }

}</source>



2
3
5
8
13
21
Invalid type: class java.lang.String


Filters enumeration to contain each of the provided elements just once.

   <source lang="java">

/*

* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common
* Development and Distribution License("CDDL") (collectively, the
* "License"). You may not use this file except in compliance with the
* License. You can obtain a copy of the License at
* http://www.netbeans.org/cddl-gplv2.html
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
* specific language governing permissions and limitations under the
* License.  When distributing the software, include this License Header
* Notice in each file and include the License file at
* nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the
* License Header, with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* Contributor(s):
*
* The Original Software is NetBeans. The Initial Developer of the Original
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
* Microsystems, Inc. All Rights Reserved.
*
* If you wish your version of this file to be governed by only the CDDL
* or only the GPL Version 2, indicate your decision by adding
* "[Contributor] elects to include this software in this distribution
* under the [CDDL or GPL Version 2] license." If you do not indicate a
* single choice of license, a recipient has the option to distribute
* your version of this file under either the CDDL, the GPL Version 2 or
* to extend the choice of license to its licensees as provided above.
* However, if you add GPL Version 2 code and therefore, elected the GPL
* Version 2 license, then the option applies only if the new code is
* made subject to such option by the copyright holder.
*/

import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Set; /**

* @since 4.37
* @author Jaroslav Tulach
*/

final class Enumerations extends Object {

   /**
    * Filters the input enumeration to new one that should contain
    * each of the provided elements just once.
    * The elements are compared
    * using their default equals and hashCode methods.
    *
    * @param en enumeration to filter
    * @return enumeration without duplicated items
    */
   public static <T> Enumeration<T> removeDuplicates(Enumeration<T> en) {
       class RDupls implements Processor<T,T> {
           private Set<T> set = new HashSet<T>();
           public T process(T o, Collection<T> nothing) {
               return set.add(o) ? o : null;
           }
       }
       return filter(en, new RDupls());
   }
   /**
    * Returns an enumeration that iterates over provided array.
    * @param arr the array of object
    * @return enumeration of those objects
    */
   public static <T> Enumeration<T> array(T... arr) {
       return Collections.enumeration(Arrays.asList(arr));
   }
   /**
    * Removes all nulls from the input enumeration.
    * @param en enumeration that can contain nulls
    * @return new enumeration without null values
    */
   public static <T> Enumeration<T> removeNulls(Enumeration<T> en) {
       return filter(en, new RNulls<T>());
   }
   /**
    * For each element of the input enumeration en asks the
    * {@link Processor} to provide a replacement.
    * The toAdd argument of the processor is always null.
    * 
    * Example to convert any objects into strings:
*
     * Processor convertToString = new Processor() {
     *     public Object process(Object obj, Collection alwaysNull) {
     *         return obj.toString(); // converts to string
     *     }
     * };
     * Enumeration strings = Enumerations.convert(elems, convertToString);
     * 
    *
    * @param en enumeration of any objects
    * @param processor a callback processor for the elements (its toAdd arguments is always null)
    * @return new enumeration where all elements has been processed
    */
   public static <T,R> Enumeration<R> convert(Enumeration<? extends T> en, Processor<T,R> processor) {
       return new AltEn<T,R>(en, processor);
   }
   /**
    * Filters some elements out from the input enumeration.
    * Just make the
    * {@link Processor} return null. Please notice the toAdd
    * argument of the processor is always null.
    * 
    * Example to remove all objects that are not strings:
*
     * Processor onlyString = new Processor() {
     *     public Object process(Object obj, Collection alwaysNull) {
     *         if (obj instanceof String) {
     *             return obj;
     *         } else {
     *             return null;
     *         }
     *     }
     * };
     * Enumeration strings = Enumerations.filter(elems, onlyString);
     * 
    *
    * @param en enumeration of any objects
    * @param filter a callback processor for the elements (its toAdd arguments is always null)
    * @return new enumeration which does not include non-processed (returned null from processor) elements
    * @see NbCollections#checkedEnumerationByFilter
    */
   public static <T,R> Enumeration<R> filter(Enumeration<? extends T> en, Processor<T,R> filter) {
       return new FilEn<T,R>(en, filter);
   }
   /**
    * Support for breadth-first enumerating.
    * Before any element is returned
    * for the resulting enumeration it is processed in the {@link Processor} and
    * the processor is allowed to modify it and also add additional elements
    * at the (current) end of the queue by calling toAdd.add
    * or toAdd.addAll. No other methods can be called on the
    * provided toAdd collection.
    * 
    * Example of doing breadth-first walk through a tree:
*
     * Processor queueSubnodes = new Processor() {
     *     public Object process(Object obj, Collection toAdd) {
     *         Node n = (Node)obj;
     *         toAdd.addAll (n.getChildrenList());
     *         return n;
     *     }
     * };
     * Enumeration strings = Enumerations.queue(elems, queueSubnodes);
     * 
    *
    * @param en initial content of the resulting enumeration
    * @param filter the processor that is called for each element and can
    *        add and addAll elements to its toAdd Collection argument and
    *        also change the value to be returned
    * @return enumeration with the initial and queued content (it can contain
    *       null if the filter returned null from its
    *       {@link Processor#process} method.
    */
   public static <T,R> Enumeration<R> queue(Enumeration<? extends T> en, Processor<T,R> filter) {
       QEn<T,R> q = new QEn<T,R>(filter);
       while (en.hasMoreElements()) {
           q.put(en.nextElement());
       }
       return q;
   }
   /**
    * Processor interface that can filter out objects from the enumeration,
    * change them or add aditional objects to the end of the current enumeration.
    */
   public static interface Processor<T,R> {
       /** @param original the object that is going to be returned from the enumeration right now
        * @return a replacement for this object
        * @param toAdd can be non-null if one can add new objects at the end of the enumeration
        */
       public R process(T original, Collection<T> toAdd);
   }
   /** Altering enumeration implementation */
   private static final class AltEn<T,R> extends Object implements Enumeration<R> {
       /** enumeration to filter */
       private Enumeration<? extends T> en;
       /** map to alter */
       private Processor<T,R> process;
       /**
       * @param en enumeration to filter
       */
       public AltEn(Enumeration<? extends T> en, Processor<T,R> process) {
           this.en = en;
           this.process = process;
       }
       /** @return true if there is more elements in the enumeration
       */
       public boolean hasMoreElements() {
           return en.hasMoreElements();
       }
       /** @return next object in the enumeration
       * @exception NoSuchElementException can be thrown if there is no next object
       *   in the enumeration
       */
       public R nextElement() {
           return process.process(en.nextElement(), null);
       }
   }
    // end of AltEn
   /** QueueEnumeration
    */
   private static class QEn<T,R> extends Object implements Enumeration<R> {
       /** next object to be returned */
       private ListItem<T> next = null;
       /** last object in the queue */
       private ListItem<T> last = null;
       /** processor to use */
       private Processor<T,R> processor;
       public QEn(Processor<T,R> p) {
           this.processor = p;
       }
       /** Put adds new object to the end of queue.
       * @param o the object to add
       */
       public void put(T o) {
           if (last != null) {
               ListItem<T> li = new ListItem<T>(o);
               last.next = li;
               last = li;
           } else {
               next = last = new ListItem<T>(o);
           }
       }
       /** Adds array of objects into the queue.
       * @param arr array of objects to put into the queue
       */
       public void put(Collection<? extends T> arr) {
           for (T e : arr) {
               put(e);
           }
       }
       /** Is there any next object?
       * @return true if there is next object, false otherwise
       */
       public boolean hasMoreElements() {
           return next != null;
       }
       /** @return next object in enumeration
       * @exception NoSuchElementException if there is no next object
       */
       public R nextElement() {
           if (next == null) {
               throw new NoSuchElementException();
           }
           T res = next.object;
           if ((next = next.next) == null) {
               last = null;
           }
           ;
           ToAdd<T,R> toAdd = new ToAdd<T,R>(this);
           R out = processor.process(res, toAdd);
           toAdd.finish();
           return out;
       }
       /** item in linked list of Objects */
       private static final class ListItem<T> {
           T object;
           ListItem<T> next;
           /** @param o the object for this item */
           ListItem(T o) {
               object = o;
           }
       }
       /** Temporary collection that supports only add and addAll operations*/
       private static final class ToAdd<T,R> extends Object implements Collection<T> {
           private QEn<T,R> q;
           public ToAdd(QEn<T,R> q) {
               this.q = q;
           }
           public void finish() {
               this.q = null;
           }
           public boolean add(T o) {
               q.put(o);
               return true;
           }
           public boolean addAll(Collection<? extends T> c) {
               q.put(c);
               return true;
           }
           private String msg() {
               return "Only add and addAll are implemented"; // NOI18N
           }
           public void clear() {
               throw new UnsupportedOperationException(msg());
           }
           public boolean contains(Object o) {
               throw new UnsupportedOperationException(msg());
           }
           public boolean containsAll(Collection c) {
               throw new UnsupportedOperationException(msg());
           }
           public boolean isEmpty() {
               throw new UnsupportedOperationException(msg());
           }
           public Iterator<T> iterator() {
               throw new UnsupportedOperationException(msg());
           }
           public boolean remove(Object o) {
               throw new UnsupportedOperationException(msg());
           }
           public boolean removeAll(Collection c) {
               throw new UnsupportedOperationException(msg());
           }
           public boolean retainAll(Collection c) {
               throw new UnsupportedOperationException(msg());
           }
           public int size() {
               throw new UnsupportedOperationException(msg());
           }
           public Object[] toArray() {
               throw new UnsupportedOperationException(msg());
           }
           public<X> X[] toArray(X[] a) {
               throw new UnsupportedOperationException(msg());
           }
       }
        // end of ToAdd
   }
    // end of QEn
   /** Filtering enumeration */
   private static final class FilEn<T,R> extends Object implements Enumeration<R> {
       /** marker object stating there is no nexte element prepared */
       private static final Object EMPTY = new Object();
       /** enumeration to filter */
       private Enumeration<? extends T> en;
       /** element to be returned next time or {@link #EMPTY} if there is
       * no such element prepared */
       private R next = empty();
       /** the set to use as filter */
       private Processor<T,R> filter;
       /**
       * @param en enumeration to filter
       */
       public FilEn(Enumeration<? extends T> en, Processor<T,R> filter) {
           this.en = en;
           this.filter = filter;
       }
       /** @return true if there is more elements in the enumeration
       */
       public boolean hasMoreElements() {
           if (next != empty()) {
               // there is a object already prepared
               return true;
           }
           while (en.hasMoreElements()) {
               // read next
               next = filter.process(en.nextElement(), null);
               if (next != null) {
                   // if the object is accepted
                   return true;
               }
               ;
           }
           next = empty();
           return false;
       }
       /** @return next object in the enumeration
       * @exception NoSuchElementException can be thrown if there is no next object
       *   in the enumeration
       */
       public R nextElement() {
           if ((next == EMPTY) && !hasMoreElements()) {
               throw new NoSuchElementException();
           }
           R res = next;
           next = empty();
           return res;
       }
       @SuppressWarnings("unchecked")
       private R empty() {
           return (R)EMPTY;
       }
   }
    // end of FilEn
   /** Returns true from contains if object is not null */
   private static class RNulls<T> implements Processor<T,T> {
       public T process(T original, Collection<T> toAdd) {
           return original;
       }
   }
    // end of RNulls

}</source>





Filters some elements out from the input enumeration.

   <source lang="java">

/*

* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common
* Development and Distribution License("CDDL") (collectively, the
* "License"). You may not use this file except in compliance with the
* License. You can obtain a copy of the License at
* http://www.netbeans.org/cddl-gplv2.html
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
* specific language governing permissions and limitations under the
* License.  When distributing the software, include this License Header
* Notice in each file and include the License file at
* nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the
* License Header, with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* Contributor(s):
*
* The Original Software is NetBeans. The Initial Developer of the Original
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
* Microsystems, Inc. All Rights Reserved.
*
* If you wish your version of this file to be governed by only the CDDL
* or only the GPL Version 2, indicate your decision by adding
* "[Contributor] elects to include this software in this distribution
* under the [CDDL or GPL Version 2] license." If you do not indicate a
* single choice of license, a recipient has the option to distribute
* your version of this file under either the CDDL, the GPL Version 2 or
* to extend the choice of license to its licensees as provided above.
* However, if you add GPL Version 2 code and therefore, elected the GPL
* Version 2 license, then the option applies only if the new code is
* made subject to such option by the copyright holder.
*/

import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Set; /**

* @since 4.37
* @author Jaroslav Tulach
*/

final class Enumerations extends Object {

   /**
    * Filters some elements out from the input enumeration.
    * Just make the
    * {@link Processor} return null. Please notice the toAdd
    * argument of the processor is always null.
    * 
    * Example to remove all objects that are not strings:
*
     * Processor onlyString = new Processor() {
     *     public Object process(Object obj, Collection alwaysNull) {
     *         if (obj instanceof String) {
     *             return obj;
     *         } else {
     *             return null;
     *         }
     *     }
     * };
     * Enumeration strings = Enumerations.filter(elems, onlyString);
     * 
    *
    * @param en enumeration of any objects
    * @param filter a callback processor for the elements (its toAdd arguments is always null)
    * @return new enumeration which does not include non-processed (returned null from processor) elements
    * @see NbCollections#checkedEnumerationByFilter
    */
   public static <T,R> Enumeration<R> filter(Enumeration<? extends T> en, Processor<T,R> filter) {
       return new FilEn<T,R>(en, filter);
   }
   /**
    * Support for breadth-first enumerating.
    * Before any element is returned
    * for the resulting enumeration it is processed in the {@link Processor} and
    * the processor is allowed to modify it and also add additional elements
    * at the (current) end of the queue by calling toAdd.add
    * or toAdd.addAll. No other methods can be called on the
    * provided toAdd collection.
    * 
    * Example of doing breadth-first walk through a tree:
*
     * Processor queueSubnodes = new Processor() {
     *     public Object process(Object obj, Collection toAdd) {
     *         Node n = (Node)obj;
     *         toAdd.addAll (n.getChildrenList());
     *         return n;
     *     }
     * };
     * Enumeration strings = Enumerations.queue(elems, queueSubnodes);
     * 
    *
    * @param en initial content of the resulting enumeration
    * @param filter the processor that is called for each element and can
    *        add and addAll elements to its toAdd Collection argument and
    *        also change the value to be returned
    * @return enumeration with the initial and queued content (it can contain
    *       null if the filter returned null from its
    *       {@link Processor#process} method.
    */
   public static <T,R> Enumeration<R> queue(Enumeration<? extends T> en, Processor<T,R> filter) {
       QEn<T,R> q = new QEn<T,R>(filter);
       while (en.hasMoreElements()) {
           q.put(en.nextElement());
       }
       return q;
   }
   /**
    * Processor interface that can filter out objects from the enumeration,
    * change them or add aditional objects to the end of the current enumeration.
    */
   public static interface Processor<T,R> {
       /** @param original the object that is going to be returned from the enumeration right now
        * @return a replacement for this object
        * @param toAdd can be non-null if one can add new objects at the end of the enumeration
        */
       public R process(T original, Collection<T> toAdd);
   }
   /** Altering enumeration implementation */
   private static final class AltEn<T,R> extends Object implements Enumeration<R> {
       /** enumeration to filter */
       private Enumeration<? extends T> en;
       /** map to alter */
       private Processor<T,R> process;
       /**
       * @param en enumeration to filter
       */
       public AltEn(Enumeration<? extends T> en, Processor<T,R> process) {
           this.en = en;
           this.process = process;
       }
       /** @return true if there is more elements in the enumeration
       */
       public boolean hasMoreElements() {
           return en.hasMoreElements();
       }
       /** @return next object in the enumeration
       * @exception NoSuchElementException can be thrown if there is no next object
       *   in the enumeration
       */
       public R nextElement() {
           return process.process(en.nextElement(), null);
       }
   }
    // end of AltEn
   /** QueueEnumeration
    */
   private static class QEn<T,R> extends Object implements Enumeration<R> {
       /** next object to be returned */
       private ListItem<T> next = null;
       /** last object in the queue */
       private ListItem<T> last = null;
       /** processor to use */
       private Processor<T,R> processor;
       public QEn(Processor<T,R> p) {
           this.processor = p;
       }
       /** Put adds new object to the end of queue.
       * @param o the object to add
       */
       public void put(T o) {
           if (last != null) {
               ListItem<T> li = new ListItem<T>(o);
               last.next = li;
               last = li;
           } else {
               next = last = new ListItem<T>(o);
           }
       }
       /** Adds array of objects into the queue.
       * @param arr array of objects to put into the queue
       */
       public void put(Collection<? extends T> arr) {
           for (T e : arr) {
               put(e);
           }
       }
       /** Is there any next object?
       * @return true if there is next object, false otherwise
       */
       public boolean hasMoreElements() {
           return next != null;
       }
       /** @return next object in enumeration
       * @exception NoSuchElementException if there is no next object
       */
       public R nextElement() {
           if (next == null) {
               throw new NoSuchElementException();
           }
           T res = next.object;
           if ((next = next.next) == null) {
               last = null;
           }
           ;
           ToAdd<T,R> toAdd = new ToAdd<T,R>(this);
           R out = processor.process(res, toAdd);
           toAdd.finish();
           return out;
       }
       /** item in linked list of Objects */
       private static final class ListItem<T> {
           T object;
           ListItem<T> next;
           /** @param o the object for this item */
           ListItem(T o) {
               object = o;
           }
       }
       /** Temporary collection that supports only add and addAll operations*/
       private static final class ToAdd<T,R> extends Object implements Collection<T> {
           private QEn<T,R> q;
           public ToAdd(QEn<T,R> q) {
               this.q = q;
           }
           public void finish() {
               this.q = null;
           }
           public boolean add(T o) {
               q.put(o);
               return true;
           }
           public boolean addAll(Collection<? extends T> c) {
               q.put(c);
               return true;
           }
           private String msg() {
               return "Only add and addAll are implemented"; // NOI18N
           }
           public void clear() {
               throw new UnsupportedOperationException(msg());
           }
           public boolean contains(Object o) {
               throw new UnsupportedOperationException(msg());
           }
           public boolean containsAll(Collection c) {
               throw new UnsupportedOperationException(msg());
           }
           public boolean isEmpty() {
               throw new UnsupportedOperationException(msg());
           }
           public Iterator<T> iterator() {
               throw new UnsupportedOperationException(msg());
           }
           public boolean remove(Object o) {
               throw new UnsupportedOperationException(msg());
           }
           public boolean removeAll(Collection c) {
               throw new UnsupportedOperationException(msg());
           }
           public boolean retainAll(Collection c) {
               throw new UnsupportedOperationException(msg());
           }
           public int size() {
               throw new UnsupportedOperationException(msg());
           }
           public Object[] toArray() {
               throw new UnsupportedOperationException(msg());
           }
           public<X> X[] toArray(X[] a) {
               throw new UnsupportedOperationException(msg());
           }
       }
        // end of ToAdd
   }
    // end of QEn
   /** Filtering enumeration */
   private static final class FilEn<T,R> extends Object implements Enumeration<R> {
       /** marker object stating there is no nexte element prepared */
       private static final Object EMPTY = new Object();
       /** enumeration to filter */
       private Enumeration<? extends T> en;
       /** element to be returned next time or {@link #EMPTY} if there is
       * no such element prepared */
       private R next = empty();
       /** the set to use as filter */
       private Processor<T,R> filter;
       /**
       * @param en enumeration to filter
       */
       public FilEn(Enumeration<? extends T> en, Processor<T,R> filter) {
           this.en = en;
           this.filter = filter;
       }
       /** @return true if there is more elements in the enumeration
       */
       public boolean hasMoreElements() {
           if (next != empty()) {
               // there is a object already prepared
               return true;
           }
           while (en.hasMoreElements()) {
               // read next
               next = filter.process(en.nextElement(), null);
               if (next != null) {
                   // if the object is accepted
                   return true;
               }
               ;
           }
           next = empty();
           return false;
       }
       /** @return next object in the enumeration
       * @exception NoSuchElementException can be thrown if there is no next object
       *   in the enumeration
       */
       public R nextElement() {
           if ((next == EMPTY) && !hasMoreElements()) {
               throw new NoSuchElementException();
           }
           R res = next;
           next = empty();
           return res;
       }
       @SuppressWarnings("unchecked")
       private R empty() {
           return (R)EMPTY;
       }
   }
    // end of FilEn
   /** Returns true from contains if object is not null */
   private static class RNulls<T> implements Processor<T,T> {
       public T process(T original, Collection<T> toAdd) {
           return original;
       }
   }
    // end of RNulls

}</source>





For each element of the input enumeration asks the Processor to provide a replacement

   <source lang="java">

/*

* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common
* Development and Distribution License("CDDL") (collectively, the
* "License"). You may not use this file except in compliance with the
* License. You can obtain a copy of the License at
* http://www.netbeans.org/cddl-gplv2.html
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
* specific language governing permissions and limitations under the
* License.  When distributing the software, include this License Header
* Notice in each file and include the License file at
* nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the
* License Header, with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* Contributor(s):
*
* The Original Software is NetBeans. The Initial Developer of the Original
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
* Microsystems, Inc. All Rights Reserved.
*
* If you wish your version of this file to be governed by only the CDDL
* or only the GPL Version 2, indicate your decision by adding
* "[Contributor] elects to include this software in this distribution
* under the [CDDL or GPL Version 2] license." If you do not indicate a
* single choice of license, a recipient has the option to distribute
* your version of this file under either the CDDL, the GPL Version 2 or
* to extend the choice of license to its licensees as provided above.
* However, if you add GPL Version 2 code and therefore, elected the GPL
* Version 2 license, then the option applies only if the new code is
* made subject to such option by the copyright holder.
*/

import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Set; /**

* @since 4.37
* @author Jaroslav Tulach
*/

final class Enumerations extends Object {

   /**
    * For each element of the input enumeration en asks the
    * {@link Processor} to provide a replacement.
    * The toAdd argument of the processor is always null.
    * 
    * Example to convert any objects into strings:
*
     * Processor convertToString = new Processor() {
     *     public Object process(Object obj, Collection alwaysNull) {
     *         return obj.toString(); // converts to string
     *     }
     * };
     * Enumeration strings = Enumerations.convert(elems, convertToString);
     * 
    *
    * @param en enumeration of any objects
    * @param processor a callback processor for the elements (its toAdd arguments is always null)
    * @return new enumeration where all elements has been processed
    */
   public static <T,R> Enumeration<R> convert(Enumeration<? extends T> en, Processor<T,R> processor) {
       return new AltEn<T,R>(en, processor);
   }
   /**
    * Filters some elements out from the input enumeration.
    * Just make the
    * {@link Processor} return null. Please notice the toAdd
    * argument of the processor is always null.
    * 
    * Example to remove all objects that are not strings:
*
     * Processor onlyString = new Processor() {
     *     public Object process(Object obj, Collection alwaysNull) {
     *         if (obj instanceof String) {
     *             return obj;
     *         } else {
     *             return null;
     *         }
     *     }
     * };
     * Enumeration strings = Enumerations.filter(elems, onlyString);
     * 
    *
    * @param en enumeration of any objects
    * @param filter a callback processor for the elements (its toAdd arguments is always null)
    * @return new enumeration which does not include non-processed (returned null from processor) elements
    * @see NbCollections#checkedEnumerationByFilter
    */
   public static <T,R> Enumeration<R> filter(Enumeration<? extends T> en, Processor<T,R> filter) {
       return new FilEn<T,R>(en, filter);
   }
   /**
    * Support for breadth-first enumerating.
    * Before any element is returned
    * for the resulting enumeration it is processed in the {@link Processor} and
    * the processor is allowed to modify it and also add additional elements
    * at the (current) end of the queue by calling toAdd.add
    * or toAdd.addAll. No other methods can be called on the
    * provided toAdd collection.
    * 
    * Example of doing breadth-first walk through a tree:
*
     * Processor queueSubnodes = new Processor() {
     *     public Object process(Object obj, Collection toAdd) {
     *         Node n = (Node)obj;
     *         toAdd.addAll (n.getChildrenList());
     *         return n;
     *     }
     * };
     * Enumeration strings = Enumerations.queue(elems, queueSubnodes);
     * 
    *
    * @param en initial content of the resulting enumeration
    * @param filter the processor that is called for each element and can
    *        add and addAll elements to its toAdd Collection argument and
    *        also change the value to be returned
    * @return enumeration with the initial and queued content (it can contain
    *       null if the filter returned null from its
    *       {@link Processor#process} method.
    */
   public static <T,R> Enumeration<R> queue(Enumeration<? extends T> en, Processor<T,R> filter) {
       QEn<T,R> q = new QEn<T,R>(filter);
       while (en.hasMoreElements()) {
           q.put(en.nextElement());
       }
       return q;
   }
   /**
    * Processor interface that can filter out objects from the enumeration,
    * change them or add aditional objects to the end of the current enumeration.
    */
   public static interface Processor<T,R> {
       /** @param original the object that is going to be returned from the enumeration right now
        * @return a replacement for this object
        * @param toAdd can be non-null if one can add new objects at the end of the enumeration
        */
       public R process(T original, Collection<T> toAdd);
   }
   /** Altering enumeration implementation */
   private static final class AltEn<T,R> extends Object implements Enumeration<R> {
       /** enumeration to filter */
       private Enumeration<? extends T> en;
       /** map to alter */
       private Processor<T,R> process;
       /**
       * @param en enumeration to filter
       */
       public AltEn(Enumeration<? extends T> en, Processor<T,R> process) {
           this.en = en;
           this.process = process;
       }
       /** @return true if there is more elements in the enumeration
       */
       public boolean hasMoreElements() {
           return en.hasMoreElements();
       }
       /** @return next object in the enumeration
       * @exception NoSuchElementException can be thrown if there is no next object
       *   in the enumeration
       */
       public R nextElement() {
           return process.process(en.nextElement(), null);
       }
   }
    // end of AltEn
   /** QueueEnumeration
    */
   private static class QEn<T,R> extends Object implements Enumeration<R> {
       /** next object to be returned */
       private ListItem<T> next = null;
       /** last object in the queue */
       private ListItem<T> last = null;
       /** processor to use */
       private Processor<T,R> processor;
       public QEn(Processor<T,R> p) {
           this.processor = p;
       }
       /** Put adds new object to the end of queue.
       * @param o the object to add
       */
       public void put(T o) {
           if (last != null) {
               ListItem<T> li = new ListItem<T>(o);
               last.next = li;
               last = li;
           } else {
               next = last = new ListItem<T>(o);
           }
       }
       /** Adds array of objects into the queue.
       * @param arr array of objects to put into the queue
       */
       public void put(Collection<? extends T> arr) {
           for (T e : arr) {
               put(e);
           }
       }
       /** Is there any next object?
       * @return true if there is next object, false otherwise
       */
       public boolean hasMoreElements() {
           return next != null;
       }
       /** @return next object in enumeration
       * @exception NoSuchElementException if there is no next object
       */
       public R nextElement() {
           if (next == null) {
               throw new NoSuchElementException();
           }
           T res = next.object;
           if ((next = next.next) == null) {
               last = null;
           }
           ;
           ToAdd<T,R> toAdd = new ToAdd<T,R>(this);
           R out = processor.process(res, toAdd);
           toAdd.finish();
           return out;
       }
       /** item in linked list of Objects */
       private static final class ListItem<T> {
           T object;
           ListItem<T> next;
           /** @param o the object for this item */
           ListItem(T o) {
               object = o;
           }
       }
       /** Temporary collection that supports only add and addAll operations*/
       private static final class ToAdd<T,R> extends Object implements Collection<T> {
           private QEn<T,R> q;
           public ToAdd(QEn<T,R> q) {
               this.q = q;
           }
           public void finish() {
               this.q = null;
           }
           public boolean add(T o) {
               q.put(o);
               return true;
           }
           public boolean addAll(Collection<? extends T> c) {
               q.put(c);
               return true;
           }
           private String msg() {
               return "Only add and addAll are implemented"; // NOI18N
           }
           public void clear() {
               throw new UnsupportedOperationException(msg());
           }
           public boolean contains(Object o) {
               throw new UnsupportedOperationException(msg());
           }
           public boolean containsAll(Collection c) {
               throw new UnsupportedOperationException(msg());
           }
           public boolean isEmpty() {
               throw new UnsupportedOperationException(msg());
           }
           public Iterator<T> iterator() {
               throw new UnsupportedOperationException(msg());
           }
           public boolean remove(Object o) {
               throw new UnsupportedOperationException(msg());
           }
           public boolean removeAll(Collection c) {
               throw new UnsupportedOperationException(msg());
           }
           public boolean retainAll(Collection c) {
               throw new UnsupportedOperationException(msg());
           }
           public int size() {
               throw new UnsupportedOperationException(msg());
           }
           public Object[] toArray() {
               throw new UnsupportedOperationException(msg());
           }
           public<X> X[] toArray(X[] a) {
               throw new UnsupportedOperationException(msg());
           }
       }
        // end of ToAdd
   }
    // end of QEn
   /** Filtering enumeration */
   private static final class FilEn<T,R> extends Object implements Enumeration<R> {
       /** marker object stating there is no nexte element prepared */
       private static final Object EMPTY = new Object();
       /** enumeration to filter */
       private Enumeration<? extends T> en;
       /** element to be returned next time or {@link #EMPTY} if there is
       * no such element prepared */
       private R next = empty();
       /** the set to use as filter */
       private Processor<T,R> filter;
       /**
       * @param en enumeration to filter
       */
       public FilEn(Enumeration<? extends T> en, Processor<T,R> filter) {
           this.en = en;
           this.filter = filter;
       }
       /** @return true if there is more elements in the enumeration
       */
       public boolean hasMoreElements() {
           if (next != empty()) {
               // there is a object already prepared
               return true;
           }
           while (en.hasMoreElements()) {
               // read next
               next = filter.process(en.nextElement(), null);
               if (next != null) {
                   // if the object is accepted
                   return true;
               }
               ;
           }
           next = empty();
           return false;
       }
       /** @return next object in the enumeration
       * @exception NoSuchElementException can be thrown if there is no next object
       *   in the enumeration
       */
       public R nextElement() {
           if ((next == EMPTY) && !hasMoreElements()) {
               throw new NoSuchElementException();
           }
           R res = next;
           next = empty();
           return res;
       }
       @SuppressWarnings("unchecked")
       private R empty() {
           return (R)EMPTY;
       }
   }
    // end of FilEn
   /** Returns true from contains if object is not null */
   private static class RNulls<T> implements Processor<T,T> {
       public T process(T original, Collection<T> toAdd) {
           return original;
       }
   }
    // end of RNulls

}</source>





If you prefer a for-loop

   <source lang="java">

import java.util.Enumeration; import java.util.Vector; public class MainClass {

 public static void main(String args[]) throws Exception {
   Vector v = new Vector();
   v.add("a");
   v.add("b");
   v.add("c");
   for (Enumeration e = v.elements(); e.hasMoreElements();) {
     Object o = e.nextElement();
     System.out.println(o);
   }
 }

}</source>



a
b
c


Removes all nulls from the input enumeration.

   <source lang="java">

/*

* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common
* Development and Distribution License("CDDL") (collectively, the
* "License"). You may not use this file except in compliance with the
* License. You can obtain a copy of the License at
* http://www.netbeans.org/cddl-gplv2.html
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
* specific language governing permissions and limitations under the
* License.  When distributing the software, include this License Header
* Notice in each file and include the License file at
* nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the
* License Header, with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* Contributor(s):
*
* The Original Software is NetBeans. The Initial Developer of the Original
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
* Microsystems, Inc. All Rights Reserved.
*
* If you wish your version of this file to be governed by only the CDDL
* or only the GPL Version 2, indicate your decision by adding
* "[Contributor] elects to include this software in this distribution
* under the [CDDL or GPL Version 2] license." If you do not indicate a
* single choice of license, a recipient has the option to distribute
* your version of this file under either the CDDL, the GPL Version 2 or
* to extend the choice of license to its licensees as provided above.
* However, if you add GPL Version 2 code and therefore, elected the GPL
* Version 2 license, then the option applies only if the new code is
* made subject to such option by the copyright holder.
*/

import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Set; /**

* @since 4.37
* @author Jaroslav Tulach
*/

final class Enumerations extends Object {

   /**
    * Removes all nulls from the input enumeration.
    * @param en enumeration that can contain nulls
    * @return new enumeration without null values
    */
   public static <T> Enumeration<T> removeNulls(Enumeration<T> en) {
       return filter(en, new RNulls<T>());
   }
   /**
    * For each element of the input enumeration en asks the
    * {@link Processor} to provide a replacement.
    * The toAdd argument of the processor is always null.
    * 
    * Example to convert any objects into strings:
*
     * Processor convertToString = new Processor() {
     *     public Object process(Object obj, Collection alwaysNull) {
     *         return obj.toString(); // converts to string
     *     }
     * };
     * Enumeration strings = Enumerations.convert(elems, convertToString);
     * 
    *
    * @param en enumeration of any objects
    * @param processor a callback processor for the elements (its toAdd arguments is always null)
    * @return new enumeration where all elements has been processed
    */
   public static <T,R> Enumeration<R> convert(Enumeration<? extends T> en, Processor<T,R> processor) {
       return new AltEn<T,R>(en, processor);
   }
   /**
    * Filters some elements out from the input enumeration.
    * Just make the
    * {@link Processor} return null. Please notice the toAdd
    * argument of the processor is always null.
    * 
    * Example to remove all objects that are not strings:
*
     * Processor onlyString = new Processor() {
     *     public Object process(Object obj, Collection alwaysNull) {
     *         if (obj instanceof String) {
     *             return obj;
     *         } else {
     *             return null;
     *         }
     *     }
     * };
     * Enumeration strings = Enumerations.filter(elems, onlyString);
     * 
    *
    * @param en enumeration of any objects
    * @param filter a callback processor for the elements (its toAdd arguments is always null)
    * @return new enumeration which does not include non-processed (returned null from processor) elements
    * @see NbCollections#checkedEnumerationByFilter
    */
   public static <T,R> Enumeration<R> filter(Enumeration<? extends T> en, Processor<T,R> filter) {
       return new FilEn<T,R>(en, filter);
   }
   /**
    * Support for breadth-first enumerating.
    * Before any element is returned
    * for the resulting enumeration it is processed in the {@link Processor} and
    * the processor is allowed to modify it and also add additional elements
    * at the (current) end of the queue by calling toAdd.add
    * or toAdd.addAll. No other methods can be called on the
    * provided toAdd collection.
    * 
    * Example of doing breadth-first walk through a tree:
*
     * Processor queueSubnodes = new Processor() {
     *     public Object process(Object obj, Collection toAdd) {
     *         Node n = (Node)obj;
     *         toAdd.addAll (n.getChildrenList());
     *         return n;
     *     }
     * };
     * Enumeration strings = Enumerations.queue(elems, queueSubnodes);
     * 
    *
    * @param en initial content of the resulting enumeration
    * @param filter the processor that is called for each element and can
    *        add and addAll elements to its toAdd Collection argument and
    *        also change the value to be returned
    * @return enumeration with the initial and queued content (it can contain
    *       null if the filter returned null from its
    *       {@link Processor#process} method.
    */
   public static <T,R> Enumeration<R> queue(Enumeration<? extends T> en, Processor<T,R> filter) {
       QEn<T,R> q = new QEn<T,R>(filter);
       while (en.hasMoreElements()) {
           q.put(en.nextElement());
       }
       return q;
   }
   /**
    * Processor interface that can filter out objects from the enumeration,
    * change them or add aditional objects to the end of the current enumeration.
    */
   public static interface Processor<T,R> {
       /** @param original the object that is going to be returned from the enumeration right now
        * @return a replacement for this object
        * @param toAdd can be non-null if one can add new objects at the end of the enumeration
        */
       public R process(T original, Collection<T> toAdd);
   }
   /** Altering enumeration implementation */
   private static final class AltEn<T,R> extends Object implements Enumeration<R> {
       /** enumeration to filter */
       private Enumeration<? extends T> en;
       /** map to alter */
       private Processor<T,R> process;
       /**
       * @param en enumeration to filter
       */
       public AltEn(Enumeration<? extends T> en, Processor<T,R> process) {
           this.en = en;
           this.process = process;
       }
       /** @return true if there is more elements in the enumeration
       */
       public boolean hasMoreElements() {
           return en.hasMoreElements();
       }
       /** @return next object in the enumeration
       * @exception NoSuchElementException can be thrown if there is no next object
       *   in the enumeration
       */
       public R nextElement() {
           return process.process(en.nextElement(), null);
       }
   }
    // end of AltEn
   /** QueueEnumeration
    */
   private static class QEn<T,R> extends Object implements Enumeration<R> {
       /** next object to be returned */
       private ListItem<T> next = null;
       /** last object in the queue */
       private ListItem<T> last = null;
       /** processor to use */
       private Processor<T,R> processor;
       public QEn(Processor<T,R> p) {
           this.processor = p;
       }
       /** Put adds new object to the end of queue.
       * @param o the object to add
       */
       public void put(T o) {
           if (last != null) {
               ListItem<T> li = new ListItem<T>(o);
               last.next = li;
               last = li;
           } else {
               next = last = new ListItem<T>(o);
           }
       }
       /** Adds array of objects into the queue.
       * @param arr array of objects to put into the queue
       */
       public void put(Collection<? extends T> arr) {
           for (T e : arr) {
               put(e);
           }
       }
       /** Is there any next object?
       * @return true if there is next object, false otherwise
       */
       public boolean hasMoreElements() {
           return next != null;
       }
       /** @return next object in enumeration
       * @exception NoSuchElementException if there is no next object
       */
       public R nextElement() {
           if (next == null) {
               throw new NoSuchElementException();
           }
           T res = next.object;
           if ((next = next.next) == null) {
               last = null;
           }
           ;
           ToAdd<T,R> toAdd = new ToAdd<T,R>(this);
           R out = processor.process(res, toAdd);
           toAdd.finish();
           return out;
       }
       /** item in linked list of Objects */
       private static final class ListItem<T> {
           T object;
           ListItem<T> next;
           /** @param o the object for this item */
           ListItem(T o) {
               object = o;
           }
       }
       /** Temporary collection that supports only add and addAll operations*/
       private static final class ToAdd<T,R> extends Object implements Collection<T> {
           private QEn<T,R> q;
           public ToAdd(QEn<T,R> q) {
               this.q = q;
           }
           public void finish() {
               this.q = null;
           }
           public boolean add(T o) {
               q.put(o);
               return true;
           }
           public boolean addAll(Collection<? extends T> c) {
               q.put(c);
               return true;
           }
           private String msg() {
               return "Only add and addAll are implemented"; // NOI18N
           }
           public void clear() {
               throw new UnsupportedOperationException(msg());
           }
           public boolean contains(Object o) {
               throw new UnsupportedOperationException(msg());
           }
           public boolean containsAll(Collection c) {
               throw new UnsupportedOperationException(msg());
           }
           public boolean isEmpty() {
               throw new UnsupportedOperationException(msg());
           }
           public Iterator<T> iterator() {
               throw new UnsupportedOperationException(msg());
           }
           public boolean remove(Object o) {
               throw new UnsupportedOperationException(msg());
           }
           public boolean removeAll(Collection c) {
               throw new UnsupportedOperationException(msg());
           }
           public boolean retainAll(Collection c) {
               throw new UnsupportedOperationException(msg());
           }
           public int size() {
               throw new UnsupportedOperationException(msg());
           }
           public Object[] toArray() {
               throw new UnsupportedOperationException(msg());
           }
           public<X> X[] toArray(X[] a) {
               throw new UnsupportedOperationException(msg());
           }
       }
        // end of ToAdd
   }
    // end of QEn
   /** Filtering enumeration */
   private static final class FilEn<T,R> extends Object implements Enumeration<R> {
       /** marker object stating there is no nexte element prepared */
       private static final Object EMPTY = new Object();
       /** enumeration to filter */
       private Enumeration<? extends T> en;
       /** element to be returned next time or {@link #EMPTY} if there is
       * no such element prepared */
       private R next = empty();
       /** the set to use as filter */
       private Processor<T,R> filter;
       /**
       * @param en enumeration to filter
       */
       public FilEn(Enumeration<? extends T> en, Processor<T,R> filter) {
           this.en = en;
           this.filter = filter;
       }
       /** @return true if there is more elements in the enumeration
       */
       public boolean hasMoreElements() {
           if (next != empty()) {
               // there is a object already prepared
               return true;
           }
           while (en.hasMoreElements()) {
               // read next
               next = filter.process(en.nextElement(), null);
               if (next != null) {
                   // if the object is accepted
                   return true;
               }
               ;
           }
           next = empty();
           return false;
       }
       /** @return next object in the enumeration
       * @exception NoSuchElementException can be thrown if there is no next object
       *   in the enumeration
       */
       public R nextElement() {
           if ((next == EMPTY) && !hasMoreElements()) {
               throw new NoSuchElementException();
           }
           R res = next;
           next = empty();
           return res;
       }
       @SuppressWarnings("unchecked")
       private R empty() {
           return (R)EMPTY;
       }
   }
    // end of FilEn
   /** Returns true from contains if object is not null */
   private static class RNulls<T> implements Processor<T,T> {
       public T process(T original, Collection<T> toAdd) {
           return original;
       }
   }
    // end of RNulls

}</source>





Returns an enumeration that iterates over provided array.

   <source lang="java">

/*

* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common
* Development and Distribution License("CDDL") (collectively, the
* "License"). You may not use this file except in compliance with the
* License. You can obtain a copy of the License at
* http://www.netbeans.org/cddl-gplv2.html
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
* specific language governing permissions and limitations under the
* License.  When distributing the software, include this License Header
* Notice in each file and include the License file at
* nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the
* License Header, with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* Contributor(s):
*
* The Original Software is NetBeans. The Initial Developer of the Original
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
* Microsystems, Inc. All Rights Reserved.
*
* If you wish your version of this file to be governed by only the CDDL
* or only the GPL Version 2, indicate your decision by adding
* "[Contributor] elects to include this software in this distribution
* under the [CDDL or GPL Version 2] license." If you do not indicate a
* single choice of license, a recipient has the option to distribute
* your version of this file under either the CDDL, the GPL Version 2 or
* to extend the choice of license to its licensees as provided above.
* However, if you add GPL Version 2 code and therefore, elected the GPL
* Version 2 license, then the option applies only if the new code is
* made subject to such option by the copyright holder.
*/

import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Set; /**

* @since 4.37
* @author Jaroslav Tulach
*/

final class Enumerations extends Object {

   /**
    * Returns an enumeration that iterates over provided array.
    * @param arr the array of object
    * @return enumeration of those objects
    */
   public static <T> Enumeration<T> array(T... arr) {
       return Collections.enumeration(Arrays.asList(arr));
   }
   /**
    * Removes all nulls from the input enumeration.
    * @param en enumeration that can contain nulls
    * @return new enumeration without null values
    */
   public static <T> Enumeration<T> removeNulls(Enumeration<T> en) {
       return filter(en, new RNulls<T>());
   }
   /**
    * For each element of the input enumeration en asks the
    * {@link Processor} to provide a replacement.
    * The toAdd argument of the processor is always null.
    * 
    * Example to convert any objects into strings:
*
     * Processor convertToString = new Processor() {
     *     public Object process(Object obj, Collection alwaysNull) {
     *         return obj.toString(); // converts to string
     *     }
     * };
     * Enumeration strings = Enumerations.convert(elems, convertToString);
     * 
    *
    * @param en enumeration of any objects
    * @param processor a callback processor for the elements (its toAdd arguments is always null)
    * @return new enumeration where all elements has been processed
    */
   public static <T,R> Enumeration<R> convert(Enumeration<? extends T> en, Processor<T,R> processor) {
       return new AltEn<T,R>(en, processor);
   }
   /**
    * Filters some elements out from the input enumeration.
    * Just make the
    * {@link Processor} return null. Please notice the toAdd
    * argument of the processor is always null.
    * 
    * Example to remove all objects that are not strings:
*
     * Processor onlyString = new Processor() {
     *     public Object process(Object obj, Collection alwaysNull) {
     *         if (obj instanceof String) {
     *             return obj;
     *         } else {
     *             return null;
     *         }
     *     }
     * };
     * Enumeration strings = Enumerations.filter(elems, onlyString);
     * 
    *
    * @param en enumeration of any objects
    * @param filter a callback processor for the elements (its toAdd arguments is always null)
    * @return new enumeration which does not include non-processed (returned null from processor) elements
    * @see NbCollections#checkedEnumerationByFilter
    */
   public static <T,R> Enumeration<R> filter(Enumeration<? extends T> en, Processor<T,R> filter) {
       return new FilEn<T,R>(en, filter);
   }
   /**
    * Support for breadth-first enumerating.
    * Before any element is returned
    * for the resulting enumeration it is processed in the {@link Processor} and
    * the processor is allowed to modify it and also add additional elements
    * at the (current) end of the queue by calling toAdd.add
    * or toAdd.addAll. No other methods can be called on the
    * provided toAdd collection.
    * 
    * Example of doing breadth-first walk through a tree:
*
     * Processor queueSubnodes = new Processor() {
     *     public Object process(Object obj, Collection toAdd) {
     *         Node n = (Node)obj;
     *         toAdd.addAll (n.getChildrenList());
     *         return n;
     *     }
     * };
     * Enumeration strings = Enumerations.queue(elems, queueSubnodes);
     * 
    *
    * @param en initial content of the resulting enumeration
    * @param filter the processor that is called for each element and can
    *        add and addAll elements to its toAdd Collection argument and
    *        also change the value to be returned
    * @return enumeration with the initial and queued content (it can contain
    *       null if the filter returned null from its
    *       {@link Processor#process} method.
    */
   public static <T,R> Enumeration<R> queue(Enumeration<? extends T> en, Processor<T,R> filter) {
       QEn<T,R> q = new QEn<T,R>(filter);
       while (en.hasMoreElements()) {
           q.put(en.nextElement());
       }
       return q;
   }
   /**
    * Processor interface that can filter out objects from the enumeration,
    * change them or add aditional objects to the end of the current enumeration.
    */
   public static interface Processor<T,R> {
       /** @param original the object that is going to be returned from the enumeration right now
        * @return a replacement for this object
        * @param toAdd can be non-null if one can add new objects at the end of the enumeration
        */
       public R process(T original, Collection<T> toAdd);
   }
   /** Altering enumeration implementation */
   private static final class AltEn<T,R> extends Object implements Enumeration<R> {
       /** enumeration to filter */
       private Enumeration<? extends T> en;
       /** map to alter */
       private Processor<T,R> process;
       /**
       * @param en enumeration to filter
       */
       public AltEn(Enumeration<? extends T> en, Processor<T,R> process) {
           this.en = en;
           this.process = process;
       }
       /** @return true if there is more elements in the enumeration
       */
       public boolean hasMoreElements() {
           return en.hasMoreElements();
       }
       /** @return next object in the enumeration
       * @exception NoSuchElementException can be thrown if there is no next object
       *   in the enumeration
       */
       public R nextElement() {
           return process.process(en.nextElement(), null);
       }
   }
    // end of AltEn
   /** QueueEnumeration
    */
   private static class QEn<T,R> extends Object implements Enumeration<R> {
       /** next object to be returned */
       private ListItem<T> next = null;
       /** last object in the queue */
       private ListItem<T> last = null;
       /** processor to use */
       private Processor<T,R> processor;
       public QEn(Processor<T,R> p) {
           this.processor = p;
       }
       /** Put adds new object to the end of queue.
       * @param o the object to add
       */
       public void put(T o) {
           if (last != null) {
               ListItem<T> li = new ListItem<T>(o);
               last.next = li;
               last = li;
           } else {
               next = last = new ListItem<T>(o);
           }
       }
       /** Adds array of objects into the queue.
       * @param arr array of objects to put into the queue
       */
       public void put(Collection<? extends T> arr) {
           for (T e : arr) {
               put(e);
           }
       }
       /** Is there any next object?
       * @return true if there is next object, false otherwise
       */
       public boolean hasMoreElements() {
           return next != null;
       }
       /** @return next object in enumeration
       * @exception NoSuchElementException if there is no next object
       */
       public R nextElement() {
           if (next == null) {
               throw new NoSuchElementException();
           }
           T res = next.object;
           if ((next = next.next) == null) {
               last = null;
           }
           ;
           ToAdd<T,R> toAdd = new ToAdd<T,R>(this);
           R out = processor.process(res, toAdd);
           toAdd.finish();
           return out;
       }
       /** item in linked list of Objects */
       private static final class ListItem<T> {
           T object;
           ListItem<T> next;
           /** @param o the object for this item */
           ListItem(T o) {
               object = o;
           }
       }
       /** Temporary collection that supports only add and addAll operations*/
       private static final class ToAdd<T,R> extends Object implements Collection<T> {
           private QEn<T,R> q;
           public ToAdd(QEn<T,R> q) {
               this.q = q;
           }
           public void finish() {
               this.q = null;
           }
           public boolean add(T o) {
               q.put(o);
               return true;
           }
           public boolean addAll(Collection<? extends T> c) {
               q.put(c);
               return true;
           }
           private String msg() {
               return "Only add and addAll are implemented"; // NOI18N
           }
           public void clear() {
               throw new UnsupportedOperationException(msg());
           }
           public boolean contains(Object o) {
               throw new UnsupportedOperationException(msg());
           }
           public boolean containsAll(Collection c) {
               throw new UnsupportedOperationException(msg());
           }
           public boolean isEmpty() {
               throw new UnsupportedOperationException(msg());
           }
           public Iterator<T> iterator() {
               throw new UnsupportedOperationException(msg());
           }
           public boolean remove(Object o) {
               throw new UnsupportedOperationException(msg());
           }
           public boolean removeAll(Collection c) {
               throw new UnsupportedOperationException(msg());
           }
           public boolean retainAll(Collection c) {
               throw new UnsupportedOperationException(msg());
           }
           public int size() {
               throw new UnsupportedOperationException(msg());
           }
           public Object[] toArray() {
               throw new UnsupportedOperationException(msg());
           }
           public<X> X[] toArray(X[] a) {
               throw new UnsupportedOperationException(msg());
           }
       }
        // end of ToAdd
   }
    // end of QEn
   /** Filtering enumeration */
   private static final class FilEn<T,R> extends Object implements Enumeration<R> {
       /** marker object stating there is no nexte element prepared */
       private static final Object EMPTY = new Object();
       /** enumeration to filter */
       private Enumeration<? extends T> en;
       /** element to be returned next time or {@link #EMPTY} if there is
       * no such element prepared */
       private R next = empty();
       /** the set to use as filter */
       private Processor<T,R> filter;
       /**
       * @param en enumeration to filter
       */
       public FilEn(Enumeration<? extends T> en, Processor<T,R> filter) {
           this.en = en;
           this.filter = filter;
       }
       /** @return true if there is more elements in the enumeration
       */
       public boolean hasMoreElements() {
           if (next != empty()) {
               // there is a object already prepared
               return true;
           }
           while (en.hasMoreElements()) {
               // read next
               next = filter.process(en.nextElement(), null);
               if (next != null) {
                   // if the object is accepted
                   return true;
               }
               ;
           }
           next = empty();
           return false;
       }
       /** @return next object in the enumeration
       * @exception NoSuchElementException can be thrown if there is no next object
       *   in the enumeration
       */
       public R nextElement() {
           if ((next == EMPTY) && !hasMoreElements()) {
               throw new NoSuchElementException();
           }
           R res = next;
           next = empty();
           return res;
       }
       @SuppressWarnings("unchecked")
       private R empty() {
           return (R)EMPTY;
       }
   }
    // end of FilEn
   /** Returns true from contains if object is not null */
   private static class RNulls<T> implements Processor<T,T> {
       public T process(T original, Collection<T> toAdd) {
           return original;
       }
   }
    // end of RNulls

}</source>





Serializable Enumeration

   <source lang="java">

/*

 * JBoss, Home of Professional Open Source
 * Copyright 2005, JBoss Inc., and individual contributors as indicated
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.NoSuchElementException; /**

* ???
*      
* @author ???
* @version $Revision: 2800 $
*/

@SuppressWarnings("unchecked") public class SerializableEnumeration

  extends ArrayList
  implements Enumeration

{

  /** The serialVersionUID */
  private static final long serialVersionUID = 8678951571196067510L;
  private int index;
  public SerializableEnumeration () {
     index = 0;
  }
  public SerializableEnumeration (Collection c) {
     super(c);
     index = 0;
  }
  
  public SerializableEnumeration (int initialCapacity) {
     super(initialCapacity);
     index = 0;
  }
  
  public boolean hasMoreElements() {
     return (index < size());
  }
 
  public Object nextElement() throws NoSuchElementException
  {
     try {
        Object nextObj = get(index);
        index++;
        return nextObj;
     }
     catch (IndexOutOfBoundsException e) {
        throw new NoSuchElementException();
     }
  }
  private void writeObject(java.io.ObjectOutputStream out)
     throws java.io.IOException
  {
     // the only thing to write is the index field
     out.defaultWriteObject();
  }
  
  private void readObject(java.io.ObjectInputStream in)
     throws java.io.IOException, ClassNotFoundException
  {
     in.defaultReadObject();
  }

}</source>





Support for breadth-first enumerating.

   <source lang="java">

/*

* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common
* Development and Distribution License("CDDL") (collectively, the
* "License"). You may not use this file except in compliance with the
* License. You can obtain a copy of the License at
* http://www.netbeans.org/cddl-gplv2.html
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
* specific language governing permissions and limitations under the
* License.  When distributing the software, include this License Header
* Notice in each file and include the License file at
* nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the
* License Header, with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* Contributor(s):
*
* The Original Software is NetBeans. The Initial Developer of the Original
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
* Microsystems, Inc. All Rights Reserved.
*
* If you wish your version of this file to be governed by only the CDDL
* or only the GPL Version 2, indicate your decision by adding
* "[Contributor] elects to include this software in this distribution
* under the [CDDL or GPL Version 2] license." If you do not indicate a
* single choice of license, a recipient has the option to distribute
* your version of this file under either the CDDL, the GPL Version 2 or
* to extend the choice of license to its licensees as provided above.
* However, if you add GPL Version 2 code and therefore, elected the GPL
* Version 2 license, then the option applies only if the new code is
* made subject to such option by the copyright holder.
*/

import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Set; /**

* @since 4.37
* @author Jaroslav Tulach
*/

final class Enumerations extends Object {

   /**
    * Support for breadth-first enumerating.
    * Before any element is returned
    * for the resulting enumeration it is processed in the {@link Processor} and
    * the processor is allowed to modify it and also add additional elements
    * at the (current) end of the queue by calling toAdd.add
    * or toAdd.addAll. No other methods can be called on the
    * provided toAdd collection.
    * 
    * Example of doing breadth-first walk through a tree:
*
     * Processor queueSubnodes = new Processor() {
     *     public Object process(Object obj, Collection toAdd) {
     *         Node n = (Node)obj;
     *         toAdd.addAll (n.getChildrenList());
     *         return n;
     *     }
     * };
     * Enumeration strings = Enumerations.queue(elems, queueSubnodes);
     * 
    *
    * @param en initial content of the resulting enumeration
    * @param filter the processor that is called for each element and can
    *        add and addAll elements to its toAdd Collection argument and
    *        also change the value to be returned
    * @return enumeration with the initial and queued content (it can contain
    *       null if the filter returned null from its
    *       {@link Processor#process} method.
    */
   public static <T,R> Enumeration<R> queue(Enumeration<? extends T> en, Processor<T,R> filter) {
       QEn<T,R> q = new QEn<T,R>(filter);
       while (en.hasMoreElements()) {
           q.put(en.nextElement());
       }
       return q;
   }
   /**
    * Processor interface that can filter out objects from the enumeration,
    * change them or add aditional objects to the end of the current enumeration.
    */
   public static interface Processor<T,R> {
       /** @param original the object that is going to be returned from the enumeration right now
        * @return a replacement for this object
        * @param toAdd can be non-null if one can add new objects at the end of the enumeration
        */
       public R process(T original, Collection<T> toAdd);
   }
   /** Altering enumeration implementation */
   private static final class AltEn<T,R> extends Object implements Enumeration<R> {
       /** enumeration to filter */
       private Enumeration<? extends T> en;
       /** map to alter */
       private Processor<T,R> process;
       /**
       * @param en enumeration to filter
       */
       public AltEn(Enumeration<? extends T> en, Processor<T,R> process) {
           this.en = en;
           this.process = process;
       }
       /** @return true if there is more elements in the enumeration
       */
       public boolean hasMoreElements() {
           return en.hasMoreElements();
       }
       /** @return next object in the enumeration
       * @exception NoSuchElementException can be thrown if there is no next object
       *   in the enumeration
       */
       public R nextElement() {
           return process.process(en.nextElement(), null);
       }
   }
    // end of AltEn
   /** QueueEnumeration
    */
   private static class QEn<T,R> extends Object implements Enumeration<R> {
       /** next object to be returned */
       private ListItem<T> next = null;
       /** last object in the queue */
       private ListItem<T> last = null;
       /** processor to use */
       private Processor<T,R> processor;
       public QEn(Processor<T,R> p) {
           this.processor = p;
       }
       /** Put adds new object to the end of queue.
       * @param o the object to add
       */
       public void put(T o) {
           if (last != null) {
               ListItem<T> li = new ListItem<T>(o);
               last.next = li;
               last = li;
           } else {
               next = last = new ListItem<T>(o);
           }
       }
       /** Adds array of objects into the queue.
       * @param arr array of objects to put into the queue
       */
       public void put(Collection<? extends T> arr) {
           for (T e : arr) {
               put(e);
           }
       }
       /** Is there any next object?
       * @return true if there is next object, false otherwise
       */
       public boolean hasMoreElements() {
           return next != null;
       }
       /** @return next object in enumeration
       * @exception NoSuchElementException if there is no next object
       */
       public R nextElement() {
           if (next == null) {
               throw new NoSuchElementException();
           }
           T res = next.object;
           if ((next = next.next) == null) {
               last = null;
           }
           ;
           ToAdd<T,R> toAdd = new ToAdd<T,R>(this);
           R out = processor.process(res, toAdd);
           toAdd.finish();
           return out;
       }
       /** item in linked list of Objects */
       private static final class ListItem<T> {
           T object;
           ListItem<T> next;
           /** @param o the object for this item */
           ListItem(T o) {
               object = o;
           }
       }
       /** Temporary collection that supports only add and addAll operations*/
       private static final class ToAdd<T,R> extends Object implements Collection<T> {
           private QEn<T,R> q;
           public ToAdd(QEn<T,R> q) {
               this.q = q;
           }
           public void finish() {
               this.q = null;
           }
           public boolean add(T o) {
               q.put(o);
               return true;
           }
           public boolean addAll(Collection<? extends T> c) {
               q.put(c);
               return true;
           }
           private String msg() {
               return "Only add and addAll are implemented"; // NOI18N
           }
           public void clear() {
               throw new UnsupportedOperationException(msg());
           }
           public boolean contains(Object o) {
               throw new UnsupportedOperationException(msg());
           }
           public boolean containsAll(Collection c) {
               throw new UnsupportedOperationException(msg());
           }
           public boolean isEmpty() {
               throw new UnsupportedOperationException(msg());
           }
           public Iterator<T> iterator() {
               throw new UnsupportedOperationException(msg());
           }
           public boolean remove(Object o) {
               throw new UnsupportedOperationException(msg());
           }
           public boolean removeAll(Collection c) {
               throw new UnsupportedOperationException(msg());
           }
           public boolean retainAll(Collection c) {
               throw new UnsupportedOperationException(msg());
           }
           public int size() {
               throw new UnsupportedOperationException(msg());
           }
           public Object[] toArray() {
               throw new UnsupportedOperationException(msg());
           }
           public<X> X[] toArray(X[] a) {
               throw new UnsupportedOperationException(msg());
           }
       }
        // end of ToAdd
   }
    // end of QEn
   /** Filtering enumeration */
   private static final class FilEn<T,R> extends Object implements Enumeration<R> {
       /** marker object stating there is no nexte element prepared */
       private static final Object EMPTY = new Object();
       /** enumeration to filter */
       private Enumeration<? extends T> en;
       /** element to be returned next time or {@link #EMPTY} if there is
       * no such element prepared */
       private R next = empty();
       /** the set to use as filter */
       private Processor<T,R> filter;
       /**
       * @param en enumeration to filter
       */
       public FilEn(Enumeration<? extends T> en, Processor<T,R> filter) {
           this.en = en;
           this.filter = filter;
       }
       /** @return true if there is more elements in the enumeration
       */
       public boolean hasMoreElements() {
           if (next != empty()) {
               // there is a object already prepared
               return true;
           }
           while (en.hasMoreElements()) {
               // read next
               next = filter.process(en.nextElement(), null);
               if (next != null) {
                   // if the object is accepted
                   return true;
               }
               ;
           }
           next = empty();
           return false;
       }
       /** @return next object in the enumeration
       * @exception NoSuchElementException can be thrown if there is no next object
       *   in the enumeration
       */
       public R nextElement() {
           if ((next == EMPTY) && !hasMoreElements()) {
               throw new NoSuchElementException();
           }
           R res = next;
           next = empty();
           return res;
       }
       @SuppressWarnings("unchecked")
       private R empty() {
           return (R)EMPTY;
       }
   }
    // end of FilEn
   /** Returns true from contains if object is not null */
   private static class RNulls<T> implements Processor<T,T> {
       public T process(T original, Collection<T> toAdd) {
           return original;
       }
   }
    // end of RNulls

}</source>





The Enumeration Interface

The Enumeration interface defines a way to traverse all the members of a collection of objects.

The hasMoreElements() method checks to see if there are more elements and returns a boolean.

If there are more elements, nextElement() will return the next element as an Object.

If there are no more elements when nextElement() is called, the runtime NoSuchElementException will be thrown.



   <source lang="java">

import java.util.Enumeration; import java.util.Vector; public class MainClass {

 public static void main(String args[]) throws Exception {
   Vector v = new Vector();
   v.add("a");
   v.add("b");
   v.add("c");
   Enumeration e = v.elements();
   while (e.hasMoreElements()) {
     Object o = e.nextElement();
     System.out.println(o);
   }
 }

}</source>



a
b
c


The SequenceInputStream Class

   <source lang="java">

import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStreamReader; import java.io.SequenceInputStream; import java.util.Enumeration; import java.util.Vector; public class MainClass {

 public static void main(String args[]) throws Exception {
   Vector v = new Vector(3);
   v.add(new FileInputStream("/a/b"));
   v.add(new FileInputStream("yourfile.bar"));
   v.add(new FileInputStream("/yourfile.txt"));
   Enumeration e = v.elements();
   SequenceInputStream sis = new SequenceInputStream(e);
   InputStreamReader isr = new InputStreamReader(sis);
   BufferedReader br = new BufferedReader(isr);
   String line;
   while ((line = br.readLine()) != null) {
     System.out.println(line);
   }
   br.close();
 }

}</source>





Where do we get the enumeration from?

Vector, Stack: elements()

Dictionary, Hashtable, Properties: elements(), keys()



   <source lang="java">

import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.Vector; public class MainClass {

 public static void main(String args[]) throws Exception {
   Vector v = new Vector();
   v.add("a");
   v.add("b");
   v.add("c");
   Collection col = v;
   Enumeration e = Collections.enumeration(col);
   
   for (; e.hasMoreElements();) {
     Object o = e.nextElement();
     System.out.println(o);
   }
 }

}</source>



a
b
c