KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > jga > algorithms > Transform


1 // ============================================================================
2
// $Id: Transform.java,v 1.5 2006/12/05 04:45:44 davidahall Exp $
3
// Copyright (c) 2002-2005 David A. Hall
4
// ============================================================================
5
// The contents of this file are subject to the Common Development and
6
// Distribution License (CDDL), Version 1.0 (the License); you may not use this
7
// file except in compliance with the License. You should have received a copy
8
// of the the License along with this file: if not, a copy of the License is
9
// available from Sun Microsystems, Inc.
10
//
11
// http://www.sun.com/cddl/cddl.html
12
//
13
// From time to time, the license steward (initially Sun Microsystems, Inc.) may
14
// publish revised and/or new versions of the License. You may not use,
15
// distribute, or otherwise make this file available under subsequent versions
16
// of the License.
17
//
18
// Alternatively, the contents of this file may be used under the terms of the
19
// GNU Lesser General Public License Version 2.1 or later (the "LGPL"), in which
20
// case the provisions of the LGPL are applicable instead of those above. If you
21
// wish to allow use of your version of this file only under the terms of the
22
// LGPL, and not to allow others to use your version of this file under the
23
// terms of the CDDL, indicate your decision by deleting the provisions above
24
// and replace them with the notice and other provisions required by the LGPL.
25
// If you do not delete the provisions above, a recipient may use your version
26
// of this file under the terms of either the CDDL or the LGPL.
27
//
28
// This library is distributed in the hope that it will be useful,
29
// but WITHOUT ANY WARRANTY; without even the implied warranty of
30
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
31
// ============================================================================
32

33 package net.sf.jga.algorithms;
34
35 import java.util.Collection JavaDoc;
36 import java.util.Iterator JavaDoc;
37 import net.sf.jga.fn.BinaryFunctor;
38 import net.sf.jga.fn.UnaryFunctor;
39 import net.sf.jga.fn.adaptor.ConditionalUnary;
40 import net.sf.jga.fn.adaptor.ConstantUnary;
41 import net.sf.jga.fn.adaptor.Identity;
42 import net.sf.jga.fn.comparison.EqualTo;
43 import net.sf.jga.util.LookAheadIterator;
44
45 import static net.sf.jga.util.ArrayUtils.*;
46 import static net.sf.jga.util.CollectionUtils.*;
47
48 /**
49  * Algorithms that process the elements of a collection, iteration, or iterable resource,
50  * and present the results.
51  * <p>
52  * Copyright &copy; 2002-2006 David A. Hall
53  *
54  * @author <a HREF="mailto:davidahall@users.sourceforge.net">David A. Hall</a>
55  **/

56 public class Transform {
57
58     static private <T> UnaryFunctor<T,T>
59     conditional(UnaryFunctor<T,Boolean JavaDoc> test, UnaryFunctor<T,T> xform)
60     {
61         return new ConditionalUnary<T,T>(test, xform, new Identity<T>());
62     }
63
64     // ============
65
// Arrays
66
// ============
67

68     /**
69      * Produces an iterable over the contents of the array, such that all instances of the
70      * given value are replaced with the given replacement value.
71      */

72     static public <T> Iterable JavaDoc<T> replace(T[] ts, T value, T replacement) {
73         return transform(ts, conditional(new EqualTo<T>().bind2nd(value),
74                                          new ConstantUnary<T,T>(replacement)));
75     }
76
77     
78     /**
79      * Produces an iterable over the contents of the array, such that all elements for which
80      * the given test returns TRUE are replaced with the given replacement value.
81      */

82     static public <T> Iterable JavaDoc<T> replace(T[] ts, UnaryFunctor<T,Boolean JavaDoc> test, T replacement) {
83         return transform(ts, conditional(test, new ConstantUnary<T,T>(replacement)));
84     }
85
86     
87     /**
88      * Produces an iterable over the contents of the array, such that all elements for which
89      * the given test returns TRUE are replaced with the results of passing that element to
90      * the given replacement functor.
91      */

92     static public <T> Iterable JavaDoc<T>
93     replace(T[] ts, UnaryFunctor<T,Boolean JavaDoc> test, UnaryFunctor<T,T> fn)
94     {
95         return transform(ts, conditional(test, fn));
96     }
97
98         
99     /**
100      * Passes each element in the array to the functor, iterating over the results
101      */

102     static public <T,R> Iterable JavaDoc<R> transform(T[] ts, UnaryFunctor<T,R> fn) {
103         return new TransformIterable<T,R>(iterable(ts), fn);
104     }
105
106     
107     /**
108      * Passes successive pairs of elements in the array to the functor, iterating over the results
109      */

110     static public <T,R> Iterable JavaDoc<R> transform(T[] ts, BinaryFunctor<T,T,R> fn) {
111         return new AdjacentIterable<T,R>(iterable(ts), fn);
112     }
113
114     
115     /**
116      * Passes corresponding pairs of elements in the arrays to the functor,
117      * iterating over the results
118      */

119     static public <T1,T2,R> Iterable JavaDoc<R> transform(T1[] ts1, T2[] ts2, BinaryFunctor<T1,T2,R> fn) {
120         return new BinaryIterable<T1,T2,R>(iterable(ts1), iterable(ts2), fn);
121     }
122     
123     // ============
124
// Iterables
125
// ============
126

127     /**
128      * Produces an iterable over the contents of the input, such that all instances of the
129      * given value are replaced with the given replacement value.
130      */

131     static public <T> Iterable JavaDoc<T> replace(Iterable JavaDoc<T> ts, T value, T replacement) {
132         return transform(ts, conditional(new EqualTo<T>().bind2nd(value),
133                                          new ConstantUnary<T,T>(replacement)));
134     }
135
136         
137     /**
138      * Produces an iterable over the contents of the input, such that all elements for which
139      * the given test returns TRUE are replaced with the given replacement value.
140      */

141     static public <T> Iterable JavaDoc<T>
142     replace(Iterable JavaDoc<T> ts, UnaryFunctor<T,Boolean JavaDoc> test, T replacement)
143     {
144         return transform(ts, conditional(test, new ConstantUnary<T,T>(replacement)));
145     }
146
147     
148     /**
149      * Produces an iterable over the contents of the input, such that all elements for which
150      * the given test returns TRUE are replaced with the results of passing that element to
151      * the given replacement functor.
152      */

153     static public <T> Iterable JavaDoc<T>
154     replace(Iterable JavaDoc<T> ts, UnaryFunctor<T,Boolean JavaDoc> test, UnaryFunctor<T,T> fn)
155     {
156         return transform(ts, conditional(test, fn));
157     }
158     
159     
160     /**
161      * Passes each element in the iterable resource to the functor, iterating over the results
162      */

163     static public <T,R> Iterable JavaDoc<R> transform(Iterable JavaDoc<? extends T> i, UnaryFunctor<T,R> fn) {
164         return new TransformIterable<T,R>(i, fn);
165     }
166
167     
168     /**
169      * Passes successive pairs of elements in the iterable resource to the functor,
170      * iterating over the results
171      */

172     static public <T,R> Iterable JavaDoc<R> transform(Iterable JavaDoc<? extends T> i, BinaryFunctor<T,T,R> fn) {
173         return new AdjacentIterable<T,R>(i, fn);
174     }
175
176     
177     /**
178      * Passes corresponding pairs of elements in the iterable resources to the functor,
179      * iterating over the results
180      */

181     static public <T1,T2,R> Iterable JavaDoc<R>
182     transform(Iterable JavaDoc<? extends T1> i1, Iterable JavaDoc<? extends T2> i2, BinaryFunctor<T1,T2,R> fn)
183     {
184         return new BinaryIterable<T1,T2,R>(i1, i2, fn);
185     }
186     
187     // ============
188
// Iterators
189
// ============
190

191     /**
192      * Produces an iterator over the contents of the given iterator, such that all instances of the
193      * given value are replaced with the given replacement value.
194      */

195     static public <T> Iterator JavaDoc<T> replace(Iterator JavaDoc<? extends T> ts, T value, T replacement) {
196         return transform(ts, conditional(new EqualTo<T>().bind2nd(value),
197                                          new ConstantUnary<T,T>(replacement)));
198     }
199
200         
201     /**
202      * Produces an iterator over the contents of the given iterator, such that all elements for which
203      * the given test returns TRUE are replaced with the given replacement value.
204      */

205     static public <T> Iterator JavaDoc<T>
206     replace(Iterator JavaDoc<? extends T> ts, UnaryFunctor<T,Boolean JavaDoc> test, T replacement)
207             {
208         return transform(ts, conditional(test, new ConstantUnary<T,T>(replacement)));
209     }
210
211     
212     /**
213      * Produces an iterator over the contents of the given iterator, such that all elements for which
214      * the given test returns TRUE are replaced with the results of passing that element to
215      * the given replacement functor.
216      */

217     static public <T> Iterator JavaDoc<T>
218     replace(Iterator JavaDoc<? extends T> ts, UnaryFunctor<T,Boolean JavaDoc> test, UnaryFunctor<T,T> fn)
219     {
220         return transform(ts, conditional(test, fn));
221     }
222
223     /**
224      * Passes each element in the iterator to the functor, iterating over the results
225      */

226     static public <T,R> Iterator JavaDoc<R> transform(Iterator JavaDoc<? extends T> iter, UnaryFunctor<T,R> fn) {
227         return new net.sf.jga.util.TransformIterator<T,R>(iter, fn);
228     }
229
230     
231     /**
232      * Passes successive pairs of elements in the iterator to the functor, iterating over the results
233      */

234     static public <T,R> Iterator JavaDoc<R> transform(Iterator JavaDoc<? extends T> iter, BinaryFunctor<T,T,R> fn) {
235         return new net.sf.jga.util.TransformAdjacentIterator<T,R>(iter, fn);
236     }
237
238     
239     /**
240      * Passes corresponding pairs of elements in the iterators to the functor,
241      * iterating over the results
242      */

243     static public <T1,T2,R> Iterator JavaDoc<R>
244     transform(Iterator JavaDoc<? extends T1> iter1, Iterator JavaDoc<? extends T2> iter2, BinaryFunctor<T1,T2,R> fn)
245     {
246         return new net.sf.jga.util.TransformBinaryIterator<T1,T2,R>(iter1, iter2, fn);
247     }
248
249     // ============
250
// IterableCopy
251
// ============
252

253     /**
254      * Appends the contents of the input to the output, such that all instances of the
255      * given value are replaced with the given replacement value
256      */

257     static public <T, TCollection extends Collection JavaDoc<? super T>> TCollection
258     replace(Iterable JavaDoc<? extends T> cin, T value, T repl, TCollection cout)
259     {
260         return append(cout, replace(cin.iterator(), value, repl));
261     }
262
263     
264     /**
265      * Appends the contents of the input to the output, such that all elements for which
266      * the given test returns TRUE are replaced with the given replacement value.
267      */

268     static public <T, TCollection extends Collection JavaDoc<? super T>> TCollection
269     replace(Iterable JavaDoc<? extends T> cin, UnaryFunctor<T,Boolean JavaDoc> test, T repl, TCollection cout)
270     {
271         return append(cout, replace(cin.iterator(), test, repl));
272     }
273
274     
275     /**
276      * Appends the contents of the input to the output, such that all elements for which
277      * the given test returns TRUE are replaced with the results of passing that element to
278      * the given replacement functor.
279      */

280     static public <T, TCollection extends Collection JavaDoc<? super T>> TCollection
281     replace(Iterable JavaDoc<? extends T> cin, UnaryFunctor<T,Boolean JavaDoc> test, UnaryFunctor<T,T> fn, TCollection cout)
282     {
283         return append(cout, replace(cin.iterator(), test, fn));
284     }
285     
286     
287     /**
288      * Appends the transformed contents of the input to the output.
289      */

290     static public <T, RCollection extends Collection JavaDoc<? super R>, R> RCollection
291     transform(Iterable JavaDoc<? extends T> cin, UnaryFunctor<T,R> fn, RCollection cout) {
292         return append(cout, transform(cin.iterator(), fn));
293     }
294     
295     
296     /**
297      * Appends the results of transforming successive pairs of elements from the input to the output.
298      */

299     static public <T, RCollection extends Collection JavaDoc<? super R>, R> RCollection
300     transform(Iterable JavaDoc<? extends T> cin, BinaryFunctor<T,T,R> fn, RCollection cout) {
301         return append(cout, transform(cin.iterator(), fn));
302     }
303     
304     
305     /**
306      * Appends the results of transforming corresponding pairs of elements from the
307      * input sto the output.
308      */

309     static public <T1, T2, RCollection extends Collection JavaDoc<? super R>, R> RCollection
310     transform(Iterable JavaDoc<? extends T1> cin1, Iterable JavaDoc<? extends T2> cin2, BinaryFunctor<T1,T2,R> fn, RCollection cout)
311     {
312         return append(cout, transform(cin1.iterator(), cin2.iterator(), fn));
313     }
314     
315     
316     /**
317      * Produces iterators that will process elements of an iterable resource and present
318      * the results.
319      * <p>
320      * Copyright &copy; 2005 David A. Hall
321      */

322
323     static public class TransformIterable<T,R> implements Iterable JavaDoc<R> {
324         // The contents
325
private Iterable JavaDoc<? extends T> _delegate;
326     
327         // The process to be applied
328
private UnaryFunctor<T,R> _fn;
329
330         /**
331          * Builds a TransformIterable for the given base.
332          * @throws IllegalArgumentException if the base iterable is null
333          */

334         public TransformIterable(Iterable JavaDoc<? extends T> base, UnaryFunctor<T,R> process) {
335             _delegate = base;
336             _fn = process;
337         }
338
339
340         // - - - - - - - - - - -
341
// Iterable<T> interface
342
// - - - - - - - - - - -
343

344         public Iterator JavaDoc<R> iterator() {
345             return new net.sf.jga.util.TransformIterator(_delegate.iterator(), _fn);
346         }
347     }
348     
349     
350     /*
351      * Iterator that returns the results of applying the given functor to the
352      * elements of the given iterator.
353      */

354     static public class TransformIterator<T,R> implements Iterator JavaDoc<R> {
355
356         // The base iterator
357
private Iterator JavaDoc<? extends T> _base;
358         
359         // Functor applied to each element of the base iterator
360
private UnaryFunctor<T,R> _fn;
361
362         /**
363          * Builds a TransformIterator that applies the given functor to each element
364          * of the given base iterator.
365          */

366         public TransformIterator(Iterator JavaDoc<? extends T> iter, UnaryFunctor<T,R> fn) {
367             _base = iter;
368             _fn = fn;
369         }
370
371         // - - - - - - - - - - -
372
// Iterator<R> interface
373
// - - - - - - - - - - -
374

375         public boolean hasNext(){
376             return _base.hasNext();
377         }
378
379         public R next() {
380             return _fn.fn(_base.next());
381         }
382
383         public void remove() { throw new UnsupportedOperationException JavaDoc(); }
384     }
385
386
387     /**
388      * Produces iterators that will process successive pairs of elements of an iterable resource
389      * and present the results.
390      */

391
392     static public class AdjacentIterable<T,R> implements Iterable JavaDoc<R> {
393         // The contents
394
private Iterable JavaDoc<? extends T> _delegate;
395     
396         // The process to be applied
397
private BinaryFunctor<T,T,R> _fn;
398
399         /**
400          * Builds a TransformIterable for the given base.
401          * @throws IllegalArgumentException if the base iterable is null
402          */

403         public AdjacentIterable(Iterable JavaDoc<? extends T> base, BinaryFunctor<T,T,R> process) {
404             _delegate = base;
405             _fn = process;
406         }
407
408         // - - - - - - - - - - -
409
// Iterable<R> interface
410
// - - - - - - - - - - -
411

412         public Iterator JavaDoc<R> iterator() {
413             return new net.sf.jga.util.TransformAdjacentIterator(_delegate.iterator(), _fn);
414         }
415     }
416     
417     
418     /**
419      * Iterator that applies a given BinaryFunctor to successive pairs of elements
420      * from a given iterator, returning the results as elements.
421      */

422     static public class AdjacentIterator<T,R> implements Iterator JavaDoc<R> {
423
424         // The base iterator
425
private LookAheadIterator<? extends T> _base;
426
427         // Functor applied to adjacent values in the base iterator
428
private BinaryFunctor<T,T,R> _fn;
429
430         /**
431          * Builds a TransormAdjacentIterator that applies the given functor to
432          * adjacent elements of the given base iterator.
433          */

434         public AdjacentIterator(Iterator JavaDoc<? extends T> iter, BinaryFunctor<T,T,R> fn) {
435             _base = new LookAheadIterator<T>(iter, 2);
436             _fn = fn;
437         }
438
439         // - - - - - - - - - - -
440
// Iterator<R> interface
441
// - - - - - - - - - - -
442

443         public boolean hasNext(){
444             return _base.hasNextPlus(2);
445         }
446
447         public R next() {
448             T next = _base.next();
449             return _fn.fn(next,_base.peek(1));
450         }
451
452         public void remove() { throw new UnsupportedOperationException JavaDoc(); }
453     }
454
455
456     /**
457      * Produces iterators that applies a given BinaryFunctor to corresponding pairs of elements
458      * from a pair of iterators, returning the results.
459      */

460
461     static public class BinaryIterable<T1,T2,R> implements Iterable JavaDoc<R> {
462         // The contents
463
private Iterable JavaDoc<? extends T1> _delegate1;
464         private Iterable JavaDoc<? extends T2> _delegate2;
465     
466         // The process to be applied
467
private BinaryFunctor<T1,T2,R> _fn;
468
469         /**
470          * Builds a TransformIterable for the given base.
471          * @throws IllegalArgumentException if the base iterable is null
472          */

473         public BinaryIterable(Iterable JavaDoc<? extends T1> base1, Iterable JavaDoc<? extends T2> base2,
474                               BinaryFunctor<T1,T2,R> process)
475         {
476             _delegate1 = base1;
477             _delegate2 = base2;
478             _fn = process;
479         }
480
481         // - - - - - - - - - - -
482
// Iterable<R> interface
483
// - - - - - - - - - - -
484

485         public Iterator JavaDoc<R> iterator() {
486             return new net.sf.jga.util.TransformBinaryIterator(_delegate1.iterator(),
487                                                                _delegate2.iterator(), _fn);
488         }
489     }
490     
491     
492     /**
493      * Iterator that applies a given BinaryFunctor to corresponding pairs of elements
494      * from a pair of iterators, returning the results.
495      */

496     static public class BinaryIterator<T1,T2,R> implements Iterator JavaDoc<R> {
497         // The two base iterators
498
private Iterator JavaDoc<? extends T1> _i1;
499         private Iterator JavaDoc<? extends T2> _i2;
500     
501         // Functor applied to corresponding elements of the base iterator
502
private BinaryFunctor<T1,T2,R> _bf;
503         
504         /**
505          * Builds a TransformBinaryIterator that applies the given functor to
506          * corresponding elements of the given base iterators.
507          */

508         public BinaryIterator(Iterator JavaDoc<? extends T1> i1, Iterator JavaDoc<? extends T2> i2, BinaryFunctor<T1,T2,R> bf) {
509             _i1 = i1;
510             _i2 = i2;
511             _bf = bf;
512         }
513
514         // - - - - - - - - - - -
515
// Iterator<R> interface
516
// - - - - - - - - - - -
517

518         public boolean hasNext() {
519             return _i1.hasNext() && _i2.hasNext();
520         }
521
522         public R next() {
523             return _bf.fn(_i1.next(), _i2.next());
524         }
525         
526         public void remove() { throw new UnsupportedOperationException JavaDoc(); }
527     }
528 }
529
Popular Tags