/* File: Seq.java * Contains: Methods for use with sequences * Author: Jeff Dalton * Created: February 1998 * Updated: Tue Jul 10 01:31:20 2001 by Jeff Dalton * Copyright: (c) 1998, 2001, AIAI, University of Edinburgh */ package ix.util; import java.util.*; import ix.util.lisp.*; /** * Seq defines some convenient methods for use with sequences, * where a sequence is an Object[], a Vector, a LList, or an * Enumeration. Enumerations are used as a common intermediate * form for conversions and are also given some operations of * their own.

* * A Collection can be used as the source of an Enumeration. * This gives us a simple, but still open-ended, ability * to handle new types.

* * Needs further modification to better fit Collections and * Iterators * * @see java.util.Collection */ public abstract class Seq { private Seq() { } // don't allow instantiation /* * Conversion from Enumerations */ public static Vector toVector(Enumeration e) { Vector v = new Vector(); while (e.hasMoreElements()) v.addElement(e.nextElement()); return v; } public static Vector fillVector(Vector v, Enumeration e) { v.removeAllElements(); while (e.hasMoreElements()) v.addElement(e.nextElement()); return v; } public static Object[] toArray(Enumeration e) { // We could, instead, have a Vector we reuse. Vector v = toVector(e); Object[] a = new Object[v.size()]; v.copyInto(a); return a; } public static LList toLList(Enumeration e) { if (e.hasMoreElements()) { Object elt = e.nextElement(); return new Cons(elt, toLList(e)); } else return Lisp.NIL; } /* * Conversion to Enumerations */ public static Enumeration elements(Vector v) { return v.elements(); } public static Enumeration elements(LList l) { return l.elements(); } public static Enumeration elements(final Object[] a) { return new Enumeration() { int i = 0; // long? public boolean hasMoreElements() { return i < a.length; } public Object nextElement() { return a[i++]; } }; } public static Enumeration elements(Collection c) { return new IteratorEnumeration(c.iterator()); } public static final class IteratorEnumeration implements Enumeration { Iterator i; public IteratorEnumeration(Iterator i) { this.i = i; } public boolean hasMoreElements() { return i.hasNext(); } public Object nextElement() { return i.next(); } } /* * Operations on Enumerations */ /** * Applies a Function1 to each element of an Enumeration * and discards the results. */ public static void forEach(final Enumeration e, final Function1 f) { while (e.hasMoreElements()) { f.funcall(e.nextElement()); } } /** * Takes an Enumeration e and a Function1 f and returns a "wrapper" * Enumeration w such that each element of w is the result of calling * f on the corresponding element of e. */ public static Enumeration map(final Enumeration e, final Function1 f) { return new Enumeration() { public boolean hasMoreElements() { return e.hasMoreElements(); } public Object nextElement() { return f.funcall(e.nextElement()); } }; } /** * Takes an Enumeration e and a Predicate1 p and returns a "wrapper" * Enumeration w such that the elements of w are the corresponding * elements of e, omitting the elements of e for which p.trueOf * returns false. */ public static Enumeration filter(final Enumeration e, final Predicate1 p) { // Requires there be no null elements in the enumeration. return new Enumeration() { Object elt = null; { findNext(); } public boolean hasMoreElements() { return elt != null; } public Object nextElement() { Debug.assert(elt != null); Object result = elt; findNext(); return result; } private void findNext() { while (e.hasMoreElements()) { elt = e.nextElement(); if (p.trueOf(elt)) return; } elt = null; } }; } /* * Some Collector utilities */ public static void addEnumeration(Collector c, Enumeration e) { while (e.hasMoreElements()) { c.addElement(e.nextElement()); } } public static Function1 elementAdder(final Collector c) { return new Function1() { public Object funcall(Object e) { c.addElement(e); return null; } }; } /* * Etc */ public static Vector shuffleVector(Vector v) { Random random = new Random(); for(int i = v.size()-1; i >= 0; i--) { int j = random.nextInt(i + 1); // needs >= Java 1.2 if (i != j) { Object tmp = v.elementAt(i); v.setElementAt(v.elementAt(j), i); v.setElementAt(tmp, j); } } return v; } }