Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

OpenList.java

Go to the documentation of this file.
00001 // file:    OpenList.java
00002 // author:  Robert M. Keller
00003 // purpose: Implement Open Lists is java
00004 
00005 import java.io.*;
00006 import java.util.*;
00007 
00008 /**
00009  * OpenList is a type of uni-directional linked list that permits sharing
00010  * of list tails.  It implements the list abstraction used in many 
00011  * languages, such as rex, Lisp, etc.
00012  */
00013 
00014 class OpenList implements Cloneable
00015 {
00016 /** 
00017  * the one and only empty OpenList.  Do not create any others.
00018  * This list is represented by a unique cell allocated for the purpose.
00019  * The first and rest are not intended to be used.  We do not use null
00020  * for this list, so that we can call methods on it.  We do not create other
00021  * empty lists so that our implementation of isEmpty() works by comparing
00022  * references.
00023  */
00024 
00025 final public static OpenList nil = cons(null, null);
00026 
00027 
00028 /** 
00029  * the default left paren used when a list is printed. 
00030  * Defaults are used when the toString() method is called, i.e. whenever
00031  * an OpenList is automatically cast to a String, as in printing.
00032  * To use different punctuation, or no punctuation, use the three-argument
00033  * toString, and supply the punctuation you want.
00034  */
00035 
00036 public static String defaultLeftParen = "[";
00037 
00038 
00039 /** the default right paren used when a list is printed */
00040 
00041 public static String defaultRightParen = "]";
00042 
00043 
00044 /** the default space used when a list is printed */
00045 
00046 public static String defaultSpacer = ", ";
00047 
00048 
00049 /** exception message for first of empty list */
00050 
00051 public static String firstException = "first() of empty list";
00052 
00053 
00054 /** exception message for rest of empty list */
00055 
00056 public static String restException = "rest() of empty list";
00057 
00058 
00059 /** exception message for nth of a list */
00060 
00061 public static String nthException = "nth of an OpenList of length ";
00062 
00063 
00064 /** part of exception message for nth of a list */
00065 
00066 public static String wherePart = ", where n == "; 
00067 
00068 
00069 /** exception message for second of a list */
00070 
00071 public static String secondException = 
00072                                      "second of an OpenList, where length() = ";
00073 
00074 
00075 /** exception message for third of a list */
00076 
00077 public static String thirdException = "third of an OpenList, where length() = ";
00078 
00079 
00080 /** the Object in the first cell of a non-empty list */
00081 
00082 private Object First;
00083 
00084 
00085 /** the rest of a list, defined to be an OpenList of all but the first cell */
00086 
00087 private OpenList Rest;  
00088 
00089 /** 
00090  * Construct an OpenList from its first and rest.
00091  * This constructor is private because it is intended that the 
00092  * pseudo-constructor (or "factory") cons be used outside.
00093  *
00094  * @param _First the first Object in the list
00095  * @param _Rest list of the rest of the objects in the list
00096  */
00097 
00098 private OpenList(Object _First, OpenList _Rest)
00099   {
00100   First = _First;
00101   Rest = _Rest;
00102   }
00103 
00104 
00105 /** 
00106  * Return a new OpenList constructed from its first and rest.
00107  *
00108  * @param _First the first Object in the list
00109  * @param _Rest list of the rest of the objects in the list
00110  * @return new OpenList from first and rest
00111  */
00112 
00113 public static OpenList cons(Object _First, OpenList _Rest)
00114   {
00115   return new OpenList(_First, _Rest);
00116   }
00117 
00118 
00119 /** 
00120  * Return a new OpenList constructed from this list and a first.
00121  *
00122  * @param _First the first Object in the list
00123  * @return new OpenList from first and rest
00124  */
00125 
00126 public OpenList cons(Object _First)
00127   {
00128   return new OpenList(_First, this);
00129   }
00130 
00131 
00132 /** 
00133  * Return the first of this non-empty OpenList.
00134  *
00135  * @return first of this list
00136  * @exception OpenListException if this list happens to be empty
00137  */
00138 
00139 public Object first() throws OpenListException
00140   {
00141   if( isEmpty() ) 
00142     {
00143     throw new OpenListException(firstException);
00144     }
00145   return First;
00146   }
00147 
00148 
00149 /** 
00150  * Return the first of the argument, a non-empty OpenList.
00151  *
00152  * @param List the list the rest of which is to be returned
00153  * @return first of the argument list
00154  * @exception OpenListException if the argument happens to be empty
00155  */
00156 
00157 public static Object first(OpenList List) throws OpenListException
00158   {
00159   return List.first();
00160   }
00161 
00162 
00163 /** 
00164  * Return the rest, i.e. all a list of all but the first of this non-empty 
00165  * OpenList.
00166  *
00167  * @return rest of this list
00168  * @exception OpenListException if this list happens to be empty
00169  */
00170 
00171 public OpenList rest() throws OpenListException
00172   {
00173   if( isEmpty() ) 
00174     {
00175     throw new OpenListException(restException);
00176     }
00177   return Rest;
00178   }
00179 
00180 
00181 /** 
00182  * Return the rest, i.e. all a list of all but the first of the argument
00183  *  non-empty OpenList.
00184  *
00185  * @parameter List the list the rest of which is to be returned
00186  * @return rest of the argument list
00187  * @exception OpenListException if the argument happens to be empty
00188  */
00189 
00190 public static OpenList rest(OpenList List) throws OpenListException
00191   {
00192   return List.rest();
00193   }
00194 
00195 
00196 /** 
00197  * Return true if this list is empty, false otherwise.
00198  * Note: Done by comparing this list to nil, which should be the <i>only</i>
00199  * way to determine whether the list is empty.
00200  * @return true if this list is empty, false otherwise
00201  */
00202 
00203 public boolean isEmpty()
00204   {
00205   return this == nil;
00206   }
00207 
00208 
00209 /** 
00210  * Return true if this list is non-empty, false otherwise.
00211  * @return true if this list is non-empty, false otherwise
00212  */
00213 
00214 public boolean nonEmpty()
00215   {
00216   return this != nil;
00217   }
00218 
00219 
00220 /** 
00221  * Return true if the argument list is empty, false otherwise.
00222  * Note: Done by comparing this list to nil, which should be the <i>only</i>
00223  * way to determine whether the list is empty.
00224  *
00225  * @param List the OpenList for which emptiness is to be determined
00226  * @return true if the argument list is empty, false otherwise
00227  */
00228 
00229 public static boolean isEmpty(OpenList List)
00230   {
00231   return List.isEmpty();
00232   }
00233 
00234 
00235 /** 
00236  * Return true if the argument list is non-empty, false otherwise.
00237   *
00238  * @param List the OpenList for which non-emptiness is to be determined
00239  * @return true if the argument list is non-empty, false otherwise
00240  */
00241 
00242 public static boolean nonEmpty(OpenList List)
00243   {
00244   return List.nonEmpty();
00245   }
00246 
00247 
00248 /** 
00249  * Create a new list formed by elements of the first argument followed by
00250  * those of the second.
00251  *
00252  * @param L1 the list providing the initial elements of the result
00253  * @param L2 the list providing the final elements of the result
00254  * @return the list containing the elements of the first list followed
00255  * by those of the second
00256  */
00257 
00258 public static OpenList append(OpenList L1, OpenList L2)
00259   {
00260   if( L1.isEmpty() )
00261     {
00262     return L2;
00263     }
00264   else
00265     {
00266     return cons(L1.first(), append(L1.rest(), L2));
00267     }
00268   }
00269 
00270 
00271 /** 
00272  * Create a new list formed by elements of this list followed by those
00273  * of the argument list.
00274  *
00275  * @param L the list providing the final elements of the result
00276  * @return the list containing the elements of this list followed
00277  * by those of the second
00278  */
00279 
00280 public OpenList append(OpenList L2)
00281   {
00282   return append(this, L2);
00283   }
00284 
00285 
00286 /** 
00287  * Return true if the first argument is a member (in the sense of being
00288  * equals) of the second argument list
00289  *
00290  * @param Ob the object being tested for membership
00291  * @param L the list in which membership is to be tested
00292  * @return true if the first argument is a member of the second, false
00293  * otherwise
00294  */
00295 
00296 public static boolean member(Object Ob, OpenList L)
00297   {
00298   for( ; L.nonEmpty(); L = L.rest() )
00299     {
00300     if( Ob.equals(L.first()) ) return true;
00301     }
00302 
00303   return false;
00304   }
00305 
00306 
00307 /** 
00308  * Return true if the first argument is a member (in the sense of being
00309  * equals) of this OpenList
00310  *
00311  * @param Ob the object being tested for membership
00312  * @return true if the first argument is a member of this list, false
00313  * otherwise
00314  */
00315 
00316 public boolean member(Object Ob)
00317   {
00318   return member(Ob, this);
00319   }
00320 
00321 
00322 /** 
00323  * Return a new list containing the elements of the argument list in
00324  * reverse order.
00325  *
00326  * @param L1 the list providing the elements
00327  * @return the reverse of the argument list
00328  */
00329 
00330 public static OpenList reverse(OpenList L1)
00331   {
00332   OpenList result = nil;
00333 
00334   for( ; L1.nonEmpty(); L1 = L1.rest() )
00335     {
00336     result = cons(L1.first(), result);
00337     }
00338 
00339   return result;
00340   }
00341 
00342 
00343 /** 
00344  * Return a new list containing the elements of the argument this list in
00345  * reverse order.
00346  *
00347  * @return the reverse of this list
00348  */
00349 
00350 public OpenList reverse()
00351   {
00352   return reverse(this);
00353   }
00354 
00355 
00356 /** 
00357  * Return the number of elements of the argument list.
00358  * @param L the list, the length of which is to be determined
00359  * @return the number of elements of the argument list
00360  */
00361 
00362 public static int length(OpenList L)
00363   {
00364   int result = 0;
00365 
00366   for( ; L.nonEmpty(); L = L.rest() )
00367     {
00368     result++;
00369     }
00370 
00371   return result;
00372   }
00373 
00374 
00375 
00376 /** 
00377  * Return the number of elements of this list.
00378  * @return the number of elements of this list
00379  */
00380 
00381 public int length()
00382   {
00383   return length(this);
00384   }
00385 
00386 
00387 
00388 /** 
00389  * Return the nth element of the second argument list, 
00390  * starting with n = 0, 1, 2, ...
00391  * If there is no nth element, throws an OpenListException so indicating.
00392  *
00393  * @param n the index (0, 1, 2, ...) of the desired element.
00394  * @param L the list from which the indexed item is selected
00395  * @return the nth element of this list
00396  * @exception OpenListException if there is no nth element
00397  */
00398 
00399 public static Object nth(int n, OpenList L) throws OpenListException
00400   {
00401   int remaining = n;
00402   OpenList original = L;
00403 
00404   try
00405     {
00406     while( remaining > 0 )
00407       {
00408       L = L.rest();
00409       remaining--;
00410       }
00411     return L.first();
00412     }
00413   catch( OpenListException e )
00414     {
00415     throw new OpenListException(nthException + original.length() 
00416                               + wherePart + n);
00417     }
00418   }
00419 
00420 
00421 /** 
00422  * Return the nth element of this list, starting with n = 0, 1, 2, ...
00423  * If there is no nth element, throws an EmptyList exception so indicating.
00424  *
00425  * @param n the index (0, 1, 2, ...) of the desired element.
00426  * @return the nth element of this list
00427  * @exception OpenListException if there is no nth element
00428  */
00429 
00430 public Object nth(int n) throws OpenListException
00431   {
00432   return nth(n, this);
00433   }
00434 
00435 
00436 /** 
00437  * Returns the first n elements of this OpenList.  If there aren't n
00438  * elements in the list, returns the entire list.  If n <= 0, returns nil.
00439  *
00440  * @param n the length of the desired prefix of this list.
00441  * @return the prefix of this list of the desired length, or the entire
00442  * list itself if the list is not as long as desired.
00443  */
00444 
00445 public OpenList prefix(int n)
00446   {
00447   if( isEmpty() || n <= 0 )
00448     {
00449     return nil;
00450     }
00451 
00452   return cons(first(), rest().prefix(n-1));
00453   }
00454 
00455 
00456 /** 
00457  * Returns the first n elements of an OpenList.  If there aren't n
00458  * elements in the list, returns the entire list.  If n <= 0, returns nil.
00459  *
00460  * @param n the length of the desired prefix of this list.
00461  * @param L the list, the prefix of which is to be extracted
00462  * @return the prefix of this list of the desired length, or the entire
00463  * list itself if the list is not as long as desired.
00464  */
00465 
00466 static public OpenList prefix(int n, OpenList L)
00467   {
00468   return L.prefix(n);
00469   }
00470 
00471 
00472 /** 
00473  * Return the second element of this OpenList, assuming it has one.
00474  *
00475  * @return the second element of this OpenList
00476  * @exception OpenListException if there is no second element
00477  */
00478 
00479 public Object second() throws OpenListException
00480   {
00481   try
00482     {
00483     return nth(1);
00484     }
00485   catch( OpenListException e )
00486     {
00487     throw new OpenListException(thirdException + length());
00488     }
00489   }
00490 
00491 
00492 /** 
00493  * Return the third element of this OpenList, assuming it has one.
00494  *
00495  * @return the third element of this OpenList
00496  * @exception OpenListException if there is no third element
00497  */
00498 
00499 public Object third() throws OpenListException
00500   {
00501   try
00502     {
00503     return nth(2);
00504     }
00505   catch( OpenListException e )
00506     {
00507     throw new OpenListException(thirdException + length());
00508     }
00509   }
00510 
00511 
00512 /** 
00513  * Return the second element of the argument OpenList, assuming it has one.
00514  *
00515  * @param L an OpenList, the second element of which is to be extracted
00516  * @return the second element L
00517  * @exception OpenListException if there is no second element
00518  */
00519 
00520 public static Object second(OpenList L) throws OpenListException
00521   {
00522   return L.second();
00523   }
00524 
00525 
00526 /** 
00527  * Return the third element of the argument OpenList, assuming it has one.
00528  *
00529  * @param L an OpenList, the third element of which is to be extracted
00530  * @return the second element L
00531  * @exception OpenListException if there is no third element
00532  */
00533 
00534 public static Object third(OpenList L) throws OpenListException
00535   {
00536   return L.third();
00537   }
00538 
00539 
00540 /** 
00541  * Return the list consisting of the argument objects, in this case the
00542  * empty list.
00543  *
00544  * @return the list consisting of the argument objects
00545  */
00546 
00547 public static OpenList list()
00548   {
00549   return nil;
00550   }
00551 
00552 
00553 /** 
00554  * Return the list consisting of the argument objects.
00555  *
00556  * @param First   the first   element in the resulting list
00557  * @return the list consisting of the argument objects
00558  */
00559 
00560 public static OpenList list(Object First)
00561   {
00562   return cons(First, nil);
00563   }
00564 
00565 
00566 /** 
00567  * Return the list consisting of the argument objects.
00568  *
00569  * @param First   the first   element in the resulting list
00570  * @param Second  the second  element in the resulting list
00571  * @return the list consisting of the argument objects
00572  */
00573 
00574 public static OpenList list(Object First, Object Second)
00575   {
00576   return cons(First, list(Second));
00577   }
00578 
00579 
00580 
00581 /** 
00582  * Return the list consisting of the argument objects.
00583  *
00584  * @param First   the first   element in the resulting list
00585  * @param Second  the second  element in the resulting list
00586  * @param Third   the third   element in the resulting list
00587  * @return the list consisting of the argument objects
00588  */
00589 
00590 public static OpenList list(Object First, Object Second, Object Third)
00591   {
00592   return cons(First, list(Second, Third));
00593   }
00594 
00595 
00596 /** 
00597  * Return the list consisting of the argument objects.
00598  *
00599  * @param First   the first   element in the resulting list
00600  * @param Second  the second  element in the resulting list
00601  * @param Third   the third   element in the resulting list
00602  * @param Fourth  the fourth  element in the resulting list
00603  * @return the list consisting of the argument objects
00604  */
00605 
00606 public static OpenList list(Object First, 
00607                             Object Second, 
00608                             Object Third, 
00609                             Object Fourth)
00610   {
00611   return cons(First, list(Second, Third, Fourth));
00612   }
00613 
00614 
00615 /** 
00616  * Return the list consisting of the argument objects.
00617  *
00618  * @param First   the first   element in the resulting list
00619  * @param Second  the second  element in the resulting list
00620  * @param Third   the third   element in the resulting list
00621  * @param Fourth  the fourth  element in the resulting list
00622  * @param Fifth   the fifth   element in the resulting list
00623  * @return the list consisting of the argument objects
00624  */
00625 
00626 public static OpenList list(Object First, 
00627                             Object Second, 
00628                             Object Third, 
00629                             Object Fourth,
00630                             Object Fifth)
00631   {
00632   return cons(First, list(Second, Third, Fourth, Fifth));
00633   }
00634 
00635 
00636 /** 
00637  * Return the list consisting of the argument objects.
00638  *
00639  * @param First   the first   element in the resulting list
00640  * @param Second  the second  element in the resulting list
00641  * @param Third   the third   element in the resulting list
00642  * @param Fourth  the fourth  element in the resulting list
00643  * @param Fifth   the fifth   element in the resulting list
00644  * @param Sixth   the sixth   element in the resulting list
00645  * @return the list consisting of the argument objects
00646  */
00647 
00648 public static OpenList list(Object First, 
00649                             Object Second, 
00650                             Object Third, 
00651                             Object Fourth,
00652                             Object Fifth,
00653                             Object Sixth)
00654   {
00655   return cons(First, list(Second, Third, Fourth, Fifth, Sixth));
00656   }
00657 
00658 
00659 /** 
00660  * Return the list consisting of the argument objects.
00661  *
00662  * @param First   the first   element in the resulting list
00663  * @param Second  the second  element in the resulting list
00664  * @param Third   the third   element in the resulting list
00665  * @param Fourth  the fourth  element in the resulting list
00666  * @param Fifth   the fifth   element in the resulting list
00667  * @param Sixth   the sixth   element in the resulting list
00668  * @param Seventh the seventh element in the resulting list
00669  * @return the list consisting of the argument objects
00670  */
00671 
00672 public static OpenList list(Object First, 
00673                             Object Second, 
00674                             Object Third, 
00675                             Object Fourth,
00676                             Object Fifth,
00677                             Object Sixth,
00678                             Object Seventh)
00679   {
00680   return cons(First, list(Second, Third, Fourth, Fifth, Sixth, Seventh));
00681   }
00682 
00683 
00684 /** 
00685  * Return true if the two OpenLists are equal, in the sense of having
00686  * the equal elements in both listss.
00687  *
00688  * @param L1 one of two OpenLists to be compared for equality
00689  * @param L2 the other of two OpenLists to be compared for equality
00690  * @return true if the arguments are equal, false otherwise
00691  */
00692 
00693 public static boolean equals(OpenList L1, OpenList L2)
00694   {
00695   // As long as both lists have elements, check for the equality of 
00696   // those elements.
00697 
00698   while( L1.nonEmpty() && L2.nonEmpty() )
00699     {
00700     if( !(L1.first().equals(L2.first())) )
00701       {
00702       return false;
00703       }
00704 
00705     L1 = L1.rest();
00706     L2 = L2.rest();
00707     }
00708 
00709   // Now at least one of the lists is empty.  
00710   // The two are equal if, and only if, both are empty.
00711 
00712   return L1.isEmpty() && L2.isEmpty();  
00713   }
00714 
00715 
00716 /** 
00717  * Return true if this list is equal to the argument list.
00718  *
00719  * @param Ob the Object to be compared with this for equality
00720  * @return true if the argument is an OpenList equal to this one.
00721  */
00722 
00723 public boolean equals(Object Ob)
00724   {
00725   if( Ob instanceof OpenList )
00726     {
00727     return equals(this, (OpenList)Ob);
00728     }
00729   return false; // An OpenList can only be equals to another OpenList
00730   }
00731 
00732 
00733 /** 
00734  * Return a clone of this OpenList.  Any Cloneable Objects in the
00735  * list will be cloned in the result.  Non-Cloneable Objects will
00736  * be included as is.
00737  * @return Object which is really an OpenList (for conformance
00738  * to the Cloneable interface)
00739  */
00740 
00741 public Object clone()
00742   {
00743   if( isEmpty() )
00744     {
00745     return nil;
00746     }
00747   return cons(Copier.maybeClone(first()), (OpenList)rest().clone());
00748   }
00749 
00750 
00751 /**
00752  * Map a Function1 function object f over an OpenList L.
00753  * @param f a member of a class that implements the Function1 interface,
00754  * i.e. that provides a method Object apply(Object).
00755  * @param L a list, the elements of which will be arguments of f
00756  * @return A list resulting from applying f to each element of L
00757  */
00758 
00759 public static OpenList map(Function1 f, OpenList L)
00760   {
00761   if( L.isEmpty() )
00762     {
00763     return nil;
00764     }
00765   else
00766     {
00767     return cons(f.apply(L.first()), map(f, L.rest()));
00768     }
00769   }
00770 
00771 
00772 /**
00773  * Map a Function1 f over this OpenList.
00774  * @param f a member of a class that implements the Function1 interface,
00775  * i.e. that provides a method Object apply(Object).
00776  * @return A list resulting from applying f to each element of L
00777  */
00778 
00779 public OpenList map(Function1 f)
00780   {
00781   return map(f, this);
00782   }
00783 
00784 
00785 /**
00786  * Map a Function1 function object f over an OpenList L, where the function
00787  * is expected to produce a list for each object, then append the results
00788  * together to get an overall list.
00789  * @param f a member of a class that implements the Function1 interface,
00790  * i.e. that provides a method Object apply(Object).
00791  * @param L a list, the elements of which will be arguments of f
00792  * @return A list resulting from applying f to each element of L then appending
00793  * the results together.
00794  */
00795 
00796 public static OpenList mappend(Function1 f, OpenList L)
00797   {
00798   if( L.isEmpty() )
00799     {
00800     return nil;
00801     }
00802   else
00803     {
00804     return append((OpenList)f.apply(L.first()), mappend(f, L.rest()));
00805     }
00806   }
00807 
00808 
00809 /**
00810  * Reduce an OpenList using Function2 b and unit u.
00811  * @param b a member of a class that implements the Function2 interface,
00812  * i.e. that provides a method Object apply(Object, Object).
00813  * @param u the unit for the function b.  This will be the value returned
00814  * if L is the empty list.
00815  * @param L the list to be reduced by the function b.
00816  * @return A list resulting from applying f to each element of L
00817  */
00818 
00819 public static Object reduce(Function2 b, Object u, OpenList L)
00820   {
00821   Object result = u;
00822   for( ; L.nonEmpty(); L = L.rest() )
00823     {
00824     result = b.apply(result, L.first());
00825     }  
00826   return result;
00827   }
00828 
00829 
00830 /**
00831  * Reduce this OpenList using Function2 b and unit u.
00832  * @param b a member of a class that implements the Function2 interface,
00833  * i.e. that provides a method Object apply(Object, Object).
00834  * @param u the unit for the function b.  This will be the value returned
00835  * @param L the list to be reduced by the function b.
00836  * @return A list resulting from applying f to each element of this.
00837  */
00838 
00839 public Object reduce(Function2 b, Object u)
00840   {
00841   return reduce(b, u, this);
00842   }
00843 
00844 
00845 /**
00846  * Find out whether the first argument occurs as the first element of
00847  * any pair in the second argument, an association list. If it does,
00848  * return the entire pair.  If not, return the empty list.
00849  *
00850  *<pre>
00851  * assoc(S, []) => [];
00852  * 
00853  * assoc(S, [[S, T] | L]) => [S, T];
00854  *
00855  * assoc(S, [_ | L]) => assoc(S, L);
00856  *</pre>
00857  */
00858 
00859 public static OpenList assoc(Object X, OpenList L)
00860   {
00861   for( ; L.nonEmpty(); L = L.rest() )
00862     {
00863     OpenList First = (OpenList)L.first();
00864 
00865     if( X.equals(First.first()) )
00866       {
00867       return First;
00868       }
00869     }
00870 
00871   return nil;
00872   }
00873 
00874 
00875 /** 
00876  * Convert this OpenList to a String, using default punctuation.
00877  *
00878  * @return String representing this OpenList
00879  */
00880 
00881 public String toString()
00882   {
00883   return toString(defaultLeftParen, defaultSpacer, defaultRightParen);
00884   }
00885 
00886 
00887 /** 
00888  * Convert this OpenList to a String, using the arguments as punctuation.
00889  *
00890  * @param leftParen String that is output before the list elements
00891  * @param spacer String that is output between list elements
00892  * @param rightParen  String that is output after the list elements
00893  * @return String representing OpenList
00894  */
00895 
00896 public String toString(String leftParen, 
00897                        String spacer, 
00898                        String rightParen)
00899   {
00900   StringBuffer buffer = new StringBuffer();
00901 
00902   buffer.append(leftParen);
00903 
00904   if( nonEmpty() )
00905     {
00906     buffer.append(first().toString());
00907     OpenList remainder = rest();
00908 
00909     while( remainder.nonEmpty() )
00910       {
00911       buffer.append(spacer);
00912       buffer.append(remainder.first());
00913       remainder = remainder.rest();
00914       }
00915     }
00916 
00917   buffer.append(rightParen);
00918   return buffer.toString();
00919   }
00920 
00921 
00922 /** 
00923  * Explode the argument String into a list of Characters wrapping
00924  * the characters of the String.
00925  *
00926  * @param String to be exploded
00927  * @return OpenList containing the characters of the String
00928  */
00929 
00930 public static OpenList explode(String s)
00931   {
00932   OpenList result = nil;
00933 
00934   for( int i = s.length()-1; i >= 0; i-- )
00935     {
00936     result = cons(new Character(s.charAt(i)), result);
00937     }
00938 
00939   return result;  
00940   }
00941 
00942 
00943 /** 
00944  * Implode the contents of an OpenList into a single String.
00945  * The list can contain any Objects, not just Characters.
00946  * The toString method is used to get the character representation of
00947  * the object.  No parentheses or spacing is added around or between
00948  * the elements of the outer list.  If these are wanted, use the 
00949  * toString method rather than implode.
00950  *
00951  * @param L the list to be imploded
00952  * @return String representing the imploded list.
00953  */
00954 
00955 public static String implode(OpenList L)
00956   {
00957   StringBuffer buffer = new StringBuffer();
00958 
00959   for( ; L.nonEmpty(); L = L.rest() )
00960     {
00961     buffer.append(L.first().toString());
00962     }
00963 
00964   return buffer.toString();
00965   }
00966 
00967 
00968 /** 
00969  * Implode this OpenList into a single String.
00970  * The list can contain any Objects, not just Characters.
00971  * The toString method is used to get the character representation of
00972  * the object.  No parentheses or spacing is added around or between
00973  * the elements of the outer list.
00974  *
00975  * @return String representing the imploded list.
00976  */
00977 
00978 public String implode()
00979   {
00980   return implode(this);
00981   }
00982 
00983 
00984 /** 
00985  * Return an array of the Objects in the argument OpenList.
00986  *
00987  * @param L the list of objects to be used as elements of the array
00988  * @return an array of the Objects in the argument OpenList
00989  */
00990 
00991 public static Object[] toArray(OpenList L)
00992   {
00993   Object a[] = new Object[L.length()];
00994 
00995   int i = 0;
00996 
00997   for( ; L.nonEmpty(); L = L.rest() )
00998     {
00999     a[i] = L.first();
01000     i++;
01001     }
01002   return a;
01003   }
01004 
01005 
01006 /** 
01007  * Return an array of the Objects in this OpenList.
01008  *
01009  * @return an array of the Objects in this OpenList
01010  */
01011 
01012 public Object[] toArray()
01013   {
01014   return toArray(this);
01015   }
01016 
01017 
01018 /** 
01019  * Create an OpenList from an array of Objects.
01020  *
01021  * @return an OpenList containing the Objects in the argument array
01022  */
01023 
01024 public static OpenList fromArray(Object a[])
01025   {
01026   OpenList result = nil;
01027 
01028   for( int i = a.length-1; i >= 0; i-- )
01029     {
01030     result = cons(a[i], result);
01031     }
01032 
01033   return result;
01034   }
01035 
01036 
01037 /** 
01038  * Return a sorted version of this list, as determined by the Comparator,
01039  * using the Quicksort algorithm
01040  *
01041  * @param comparator used to determine whether one element is less than
01042  *        another
01043  * @return the list consisting of the Objects in the original list
01044  *         in order as determined by the comparator
01045  */
01046 
01047 public OpenList sort(java.util.Comparator comparator)
01048   {
01049   Object a[] = this.toArray();
01050 
01051   Quicksort q = new Quicksort(a);
01052 
01053   q.sort(comparator);
01054 
01055   return fromArray(a);
01056   }
01057   
01058 
01059 /**
01060  * Read lines from a BufferedReader, each as a separate String.
01061  * The lines read are returned as an OpenList of Strings.
01062  *
01063  *@param reader reads the lines that are compiled into a list
01064  *@return list of Strings read, one String per line
01065  */
01066 
01067 public static OpenList readLines(BufferedReader reader) throws IOException
01068   {
01069   String stringRead = reader.readLine();
01070 
01071   if( stringRead == null )
01072     return nil;
01073 
01074   return cons(stringRead, readLines(reader));
01075   }
01076 
01077 
01078 /**
01079  * Return an Enumeration of the elements of this OpenList.
01080  *@return an Enumeration of the elements of this OpenList
01081  */
01082 
01083 public Enumeration elements()
01084   {
01085   return new OpenListEnumeration(this);
01086   }
01087 
01088 
01089 /**
01090  * Create an OpenList of the elements from an Enumeration.
01091  *@param E an Enumeration that provides the elements for a new OpenList
01092  *@return an OpenList of the elements from an Enumeration
01093  */
01094 
01095 public static OpenList solidify(Enumeration E)
01096   {
01097   if( E.hasMoreElements() )
01098     {
01099     return cons(E.nextElement(), solidify(E));
01100     }
01101   else
01102     {
01103     return nil;
01104     }
01105   }
01106 
01107 
01108 /** 
01109  * test program:
01110  * exercises a variety of the defined methods, printing out results
01111  */
01112 
01113 public static void main(String arg[])
01114 {
01115 Integer zero   = new Integer(0);
01116 Integer one    = new Integer(1);
01117 Integer two    = new Integer(2);
01118 Integer three  = new Integer(3);
01119 Integer four   = new Integer(4);
01120 
01121 try
01122   {
01123   System.out.println("zero  = " + zero );
01124   System.out.println("one   = " + one  );
01125   System.out.println("two   = " + two  );
01126   System.out.println("three = " + three);
01127   System.out.println("four  = " + four );
01128 
01129   OpenList L0 = nil;
01130 
01131   System.out.println("L0 = " + L0);
01132 
01133   OpenList L1 = cons("a", cons("b", cons("c", nil)));
01134 
01135   System.out.println("L1 = " + L1);
01136 
01137   OpenList L2 = cons(cons("b", cons("c", nil)), cons("d", nil));
01138 
01139   System.out.println("L2 = " + L2);
01140 
01141   OpenList L3 = cons(L1, cons(L2, nil));
01142 
01143   System.out.println("L3 = " + L3);
01144 
01145   OpenList L4 = cons(L1, L2);
01146 
01147   System.out.println("L4 = " + L4);
01148 
01149   OpenList L5 = cons(L2, L1);
01150 
01151   System.out.println("L5 = " + L5);
01152 
01153   OpenList L6 = cons(one, nil);
01154 
01155   System.out.println("L6 = " + L6);
01156 
01157   OpenList L7 = cons(one, cons(two, cons(three, cons(four, nil))));
01158 
01159   System.out.println("L7 = " + L7);
01160 
01161   System.out.println("append(L1, L2) = " + append(L1, L2));
01162 
01163   System.out.println("reverse(L5) = " + reverse(L5));
01164 
01165   System.out.println("append(reverse(L7), reverse(L1)) = "
01166                     + append(reverse(L7), reverse(L1)));
01167 
01168   System.out.println("reverse(append(L1, L7)) = "
01169                     + reverse(append(L1, L7)));
01170 
01171   System.out.println("L5.length() = " + L5.length());
01172 
01173   System.out.println("L5.nth(2) = " + L5.nth(2));
01174 
01175   System.out.println("L5.prefix(3) = " + L5.prefix(3));
01176 
01177   System.out.println("explode(\"Hello, World\") = " 
01178                    + explode("Hello, World"));
01179 
01180   System.out.println("implode(explode(\"Hello, World\")) = " 
01181                    + implode(explode("Hello, World")));
01182 
01183   System.out.println("equals(append(reverse(L1), reverse(L2)), "
01184                     +      " reverse(append(L2, L1))) = "
01185                     + equals(append(reverse(L1), reverse(L2)),
01186                              reverse(append(L2, L1))));
01187 
01188   System.out.println("L7.equals(reverse(reverse(L7))) = "
01189                    + L7.equals(reverse(reverse(L7))));
01190 
01191   System.out.println("map(new Scaler(three), L7) = " 
01192                     + map(new Scaler(three), L7));
01193 
01194   System.out.println("map(new Scaler(new Float(3.0)), L7) = " 
01195                     + map(new Scaler(new Float(3.0)), L7));
01196 
01197   System.out.println("reduce(new Multiplier(), one,  L7) = "
01198                     + reduce(new Multiplier(), one,  L7));
01199 
01200   System.out.println("reduce(new Multiplier(), new Float(1.0),  L7) = "
01201                     + reduce(new Multiplier(), new Float(1.0),  L7));
01202 
01203   System.out.println("map(new Ranger(zero, one), L7) = " 
01204                     + map(new Ranger(zero, one), L7));
01205 
01206   System.out.println("mappend(new Ranger(zero, one), L7) = " 
01207                     + mappend(new Ranger(zero, one), L7));
01208 
01209   // This will intentionally throw an exception.
01210 
01211   System.out.println("L5.nth(4) = " + L5.nth(4));
01212 
01213   }
01214 catch( Exception e )
01215   {
01216   System.err.println("*** caught: " + e);
01217   }
01218 }
01219 }
01220 
01221 /* Output from main:
01222 
01223 zero  = 0
01224 one   = 1
01225 two   = 2
01226 three = 3
01227 four  = 4
01228 L0 = []
01229 L1 = [a, b, c]
01230 L2 = [[b, c], d]
01231 L3 = [[a, b, c], [[b, c], d]]
01232 L4 = [[a, b, c], [b, c], d]
01233 L5 = [[[b, c], d], a, b, c]
01234 L6 = [1]
01235 L7 = [1, 2, 3, 4]
01236 append(L1, L2) = [a, b, c, [b, c], d]
01237 reverse(L5) = [c, b, a, [[b, c], d]]
01238 append(reverse(L7), reverse(L1)) = [4, 3, 2, 1, c, b, a]
01239 reverse(append(L1, L7)) = [4, 3, 2, 1, c, b, a]
01240 L5.length() = 4
01241 L5.nth(2) = b
01242 L5.prefix(3) = [[[b, c], d], a, b]
01243 explode("Hello, World") = [H, e, l, l, o, ,,  , W, o, r, l, d]
01244 implode(explode("Hello, World")) = Hello, World
01245 equals(append(reverse(L1), reverse(L2)),  reverse(append(L2, L1))) = true
01246 L7.equals(reverse(reverse(L7))) = true
01247 map(new Scaler(three), L7) = [3, 6, 9, 12]
01248 map(new Scaler(new Float(3.0)), L7) = [3.0, 6.0, 9.0, 12.0]
01249 reduce(new Multiplier(), one,  L7) = 24
01250 reduce(new Multiplier(), new Float(1.0),  L7) = 24.0
01251 map(new Ranger(zero, one), L7) = [[0, 1], [0, 1, 2], [0, 1, 2, 3], [0, 1, 2, 3, 4]]
01252 mappend(new Ranger(zero, one), L7) = [0, 1, 0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4]
01253 *** caught: OpenListException: nth of an OpenList of length 4, where n == 4
01254 
01255 */

Generated at Wed Feb 19 23:28:36 2003 for OpenList by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001