View Javadoc

1   package sharin.unlinq;
2   
3   import java.lang.reflect.Array;
4   import java.util.ArrayList;
5   import java.util.Arrays;
6   import java.util.Collections;
7   import java.util.Comparator;
8   import java.util.HashMap;
9   import java.util.HashSet;
10  import java.util.Iterator;
11  import java.util.LinkedHashMap;
12  import java.util.List;
13  import java.util.Map;
14  import java.util.NoSuchElementException;
15  import java.util.Queue;
16  import java.util.Set;
17  import java.util.Map.Entry;
18  
19  import sharin.util.ArrayUtils;
20  
21  public class BasicEnumerable<T> implements Enumerable<T> {
22  
23      private final Iterable<T> iterable;
24  
25      public BasicEnumerable(Iterable<T> iterable) {
26  
27          if (iterable == null) {
28              iterable = Collections.<T> emptyList();
29          }
30  
31          this.iterable = iterable;
32      }
33  
34      public Iterator<T> iterator() {
35          return iterable.iterator();
36      }
37  
38      public static <E> Enumerable<E> from(Iterable<E> iterable) {
39          return new BasicEnumerable<E>(iterable);
40      }
41  
42      public static <E> Enumerable<E> from(E... objects) {
43  
44          if (objects == null) {
45              return new BasicEnumerable<E>(null);
46          }
47  
48          return new BasicEnumerable<E>(Arrays.asList(objects));
49      }
50  
51      public static Enumerable<Boolean> fromBoolean(boolean... values) {
52          return new BasicEnumerable<Boolean>(Arrays.asList(ArrayUtils
53                  .toWrappers(values)));
54      }
55  
56      public static Enumerable<Byte> fromByte(byte... values) {
57          return new BasicEnumerable<Byte>(Arrays.asList(ArrayUtils
58                  .toWrappers(values)));
59      }
60  
61      public static Enumerable<Character> fromChar(char... values) {
62          return new BasicEnumerable<Character>(Arrays.asList(ArrayUtils
63                  .toWrappers(values)));
64      }
65  
66      public static Enumerable<Short> fromShort(short... values) {
67          return new BasicEnumerable<Short>(Arrays.asList(ArrayUtils
68                  .toWrappers(values)));
69      }
70  
71      public static Enumerable<Integer> from(int... values) {
72          return new BasicEnumerable<Integer>(Arrays.asList(ArrayUtils
73                  .toWrappers(values)));
74      }
75  
76      public static Enumerable<Long> fromLong(long... values) {
77          return new BasicEnumerable<Long>(Arrays.asList(ArrayUtils
78                  .toWrappers(values)));
79      }
80  
81      public static Enumerable<Float> fromFloat(float... values) {
82          return new BasicEnumerable<Float>(Arrays.asList(ArrayUtils
83                  .toWrappers(values)));
84      }
85  
86      public static Enumerable<Double> fromDouble(double... values) {
87          return new BasicEnumerable<Double>(Arrays.asList(ArrayUtils
88                  .toWrappers(values)));
89      }
90  
91      public T aggregate(Func2<T, T, T> func) {
92          Iterator<T> iterator = iterable.iterator();
93          T seed = iterator.next();
94          return doAggregate(seed, func, iterator);
95      }
96  
97      public <A> A aggregate(A seed, Func2<A, T, A> func) {
98          return doAggregate(seed, func, iterable.iterator());
99      }
100 
101     public <A, R> R aggregate(A seed, Func2<A, T, A> func,
102             Func<A, R> resultSelector) {
103 
104         A a = doAggregate(seed, func, iterable.iterator());
105         return resultSelector.call(a);
106     }
107 
108     private <A> A doAggregate(A seed, Func2<A, T, A> func, Iterator<T> iterator) {
109         A a = seed;
110 
111         while (iterator.hasNext()) {
112             a = func.call(a, iterator.next());
113         }
114 
115         return a;
116     }
117 
118     public Boolean all(Func<T, Boolean> predicate) {
119 
120         for (T t : iterable) {
121 
122             if (!predicate.call(t)) {
123                 return false;
124             }
125         }
126 
127         return true;
128     }
129 
130     public Boolean any() {
131         return iterable.iterator().hasNext();
132     }
133 
134     public Boolean any(Func<T, Boolean> predicate) {
135 
136         for (T t : iterable) {
137 
138             if (predicate.call(t)) {
139                 return true;
140             }
141         }
142 
143         return false;
144     }
145 
146     public double average() {
147         Iterator<T> iterator = iterable.iterator();
148         double sum = (Integer) iterator.next();
149         int count = 1;
150 
151         while (iterator.hasNext()) {
152             sum += (Integer) iterator.next();
153             count++;
154         }
155 
156         return sum / count;
157     }
158 
159     public double averageLong() {
160         Iterator<T> iterator = iterable.iterator();
161         double sum = (Long) iterator.next();
162         int count = 1;
163 
164         while (iterator.hasNext()) {
165             sum += (Long) iterator.next();
166             count++;
167         }
168 
169         return sum / count;
170     }
171 
172     public float averageFloat() {
173         Iterator<T> iterator = iterable.iterator();
174         float sum = (Float) iterator.next();
175         int count = 1;
176 
177         while (iterator.hasNext()) {
178             sum += (Float) iterator.next();
179             count++;
180         }
181 
182         return sum / count;
183     }
184 
185     public double averageDouble() {
186         Iterator<T> iterator = iterable.iterator();
187         double sum = (Double) iterator.next();
188         int count = 1;
189 
190         while (iterator.hasNext()) {
191             sum += (Double) iterator.next();
192             count++;
193         }
194 
195         return sum / count;
196     }
197 
198     public double average(Func<T, Integer> selector) {
199         Iterator<T> iterator = iterable.iterator();
200         double sum = selector.call(iterator.next());
201         int count = 1;
202 
203         while (iterator.hasNext()) {
204             sum += selector.call(iterator.next());
205             count++;
206         }
207 
208         return sum / count;
209     }
210 
211     public double averageLong(Func<T, Long> selector) {
212         Iterator<T> iterator = iterable.iterator();
213         double sum = selector.call(iterator.next());
214         int count = 1;
215 
216         while (iterator.hasNext()) {
217             sum += selector.call(iterator.next());
218             count++;
219         }
220 
221         return sum / count;
222     }
223 
224     public float averageFloat(Func<T, Float> selector) {
225         Iterator<T> iterator = iterable.iterator();
226         float sum = selector.call(iterator.next());
227         int count = 1;
228 
229         while (iterator.hasNext()) {
230             sum += selector.call(iterator.next());
231             count++;
232         }
233 
234         return sum / count;
235     }
236 
237     public double averageDouble(Func<T, Double> selector) {
238         Iterator<T> iterator = iterable.iterator();
239         double sum = selector.call(iterator.next());
240         int count = 1;
241 
242         while (iterator.hasNext()) {
243             sum += selector.call(iterator.next());
244             count++;
245         }
246 
247         return sum / count;
248     }
249 
250     public <R> Enumerable<R> cast(final Class<R> resultClass) {
251         return new BasicEnumerable<R>(new Iterable<R>() {
252 
253             public Iterator<R> iterator() {
254                 return new Iterator<R>() {
255 
256                     private final Iterator<T> iterator = iterable.iterator();
257 
258                     public boolean hasNext() {
259                         return iterator.hasNext();
260                     }
261 
262                     public R next() {
263                         return resultClass.cast(iterator.next());
264                     }
265 
266                     public void remove() {
267                         throw new UnsupportedOperationException();
268                     }
269                 };
270             }
271         });
272     }
273 
274     public Enumerable<T> concat(final Enumerable<T> second) {
275         return new BasicEnumerable<T>(new Iterable<T>() {
276 
277             public Iterator<T> iterator() {
278                 return new QueuedIterator<T, T, T>(new ConcatenatedIterator<T>(
279                         iterable.iterator(), second.iterator())) {
280 
281                     @Override
282                     protected void addElement(Queue<T> queue, T t) {
283                         queue.add(t);
284                     }
285 
286                     @Override
287                     protected T toResult(T e) {
288                         return e;
289                     }
290                 };
291             }
292         });
293     }
294 
295     public boolean contains(Object o) {
296 
297         for (T t : iterable) {
298 
299             if (equals(o, t)) {
300                 return true;
301             }
302         }
303 
304         return false;
305     }
306 
307     private boolean equals(Object o1, Object o2) {
308 
309         if (o2 == null) {
310 
311             if (o1 == null) {
312                 return true;
313             }
314 
315         } else {
316 
317             if (o2.equals(o1)) {
318                 return true;
319             }
320         }
321 
322         return false;
323     }
324 
325     public int count() {
326         int c = 0;
327 
328         for (Iterator<T> it = iterable.iterator(); it.hasNext(); it.next()) {
329             c++;
330         }
331 
332         return c;
333     }
334 
335     public int count(Func<T, Boolean> predicate) {
336         int c = 0;
337 
338         for (T t : iterable) {
339 
340             if (predicate.call(t)) {
341                 c++;
342             }
343         }
344 
345         return c;
346     }
347 
348     public Enumerable<T> defaultIfEmpty() {
349         return defaultIfEmpty(null);
350     }
351 
352     public Enumerable<T> defaultIfEmpty(T defaultValue) {
353 
354         if (iterable.iterator().hasNext()) {
355             return new BasicEnumerable<T>(iterable);
356         }
357 
358         List<T> list = new ArrayList<T>();
359         list.add(defaultValue);
360         return new BasicEnumerable<T>(list);
361     }
362 
363     public Enumerable<T> distinct() {
364         return new BasicEnumerable<T>(new Iterable<T>() {
365 
366             public Iterator<T> iterator() {
367                 return new QueuedIterator<T, T, T>(iterable.iterator()) {
368 
369                     private final Set<T> set = new HashSet<T>();
370 
371                     @Override
372                     protected void addElement(Queue<T> queue, T t) {
373 
374                         if (!set.contains(t)) {
375                             queue.add(t);
376                             set.add(t);
377                         }
378                     }
379 
380                     @Override
381                     protected T toResult(T e) {
382                         return e;
383                     }
384                 };
385             }
386         });
387     }
388 
389     public T elementAt(int index) {
390         Iterator<T> iterator = iterable.iterator();
391 
392         for (int i = 0; i < index; i++) {
393             iterator.next();
394         }
395 
396         return iterator.next();
397     }
398 
399     public T elementAtOrDefault(int index) {
400         return elementAtOrDefault(index, null);
401     }
402 
403     public T elementAtOrDefault(int index, T defaultValue) {
404         Iterator<T> iterator = iterable.iterator();
405 
406         for (int i = 0; i < index; i++) {
407 
408             if (!iterator.hasNext()) {
409                 return defaultValue;
410             }
411 
412             iterator.next();
413         }
414 
415         if (!iterator.hasNext()) {
416             return defaultValue;
417         }
418 
419         return iterator.next();
420     }
421 
422     public static <R> Enumerable<R> empty() {
423         return new BasicEnumerable<R>((Iterable<R>) null);
424     }
425 
426     public Enumerable<T> except(final Enumerable<T> second) {
427         return new BasicEnumerable<T>(new Iterable<T>() {
428 
429             public Iterator<T> iterator() {
430                 return new QueuedIterator<T, T, T>(iterable.iterator()) {
431 
432                     private final Set<T> firstSet = new HashSet<T>();
433 
434                     private final Set<T> secondSet = new HashSet<T>(second
435                             .toList());
436 
437                     @Override
438                     protected void addElement(Queue<T> queue, T t) {
439 
440                         if (!secondSet.contains(t) && !firstSet.contains(t)) {
441                             queue.add(t);
442                             firstSet.add(t);
443                         }
444                     }
445 
446                     @Override
447                     protected T toResult(T e) {
448                         return e;
449                     }
450                 };
451             }
452         });
453     }
454 
455     public T first() {
456         return iterable.iterator().next();
457     }
458 
459     public T first(Func<T, Boolean> predicate) {
460 
461         for (T t : iterable) {
462 
463             if (predicate.call(t)) {
464                 return t;
465             }
466         }
467 
468         throw new NoSuchElementException();
469     }
470 
471     public T firstOrDefault() {
472         return firstOrDefault((T) null);
473     }
474 
475     public T firstOrDefault(T defaultValue) {
476         Iterator<T> iterator = iterable.iterator();
477 
478         if (!iterator.hasNext()) {
479             return defaultValue;
480         }
481 
482         return iterator.next();
483     }
484 
485     public T firstOrDefault(Func<T, Boolean> predicate) {
486         return firstOrDefault(predicate, null);
487     }
488 
489     public T firstOrDefault(Func<T, Boolean> predicate, T defaultValue) {
490 
491         for (T t : iterable) {
492 
493             if (predicate.call(t)) {
494                 return t;
495             }
496         }
497 
498         return defaultValue;
499     }
500 
501     public <K> Enumerable<Grouping<K, T>> groupBy(Func<T, K> keySelector) {
502         return groupBy(keySelector, getPassThroughFunc());
503     }
504 
505     public <K, R> Enumerable<R> groupBy(Func<T, K> keySelector,
506             Func2<K, Enumerable<T>, R> resultSelector) {
507 
508         return groupBy(keySelector, getPassThroughFunc(), resultSelector);
509     }
510 
511     public <K, E> Enumerable<Grouping<K, E>> groupBy(Func<T, K> keySelector,
512             Func<T, E> elementSelector) {
513 
514         LinkedHashMap<K, List<E>> map = doGroupBy(keySelector, elementSelector);
515         List<Grouping<K, E>> groupList = new ArrayList<Grouping<K, E>>();
516 
517         for (Entry<K, List<E>> entry : map.entrySet()) {
518             groupList.add(new BasicGrouping<K, E>(entry.getKey(),
519                     new BasicEnumerable<E>(entry.getValue())));
520         }
521 
522         return new BasicEnumerable<Grouping<K, E>>(groupList);
523     }
524 
525     public <K, E, R> Enumerable<R> groupBy(Func<T, K> keySelector,
526             Func<T, E> elementSelector,
527             Func2<K, Enumerable<E>, R> resultSelector) {
528 
529         LinkedHashMap<K, List<E>> map = doGroupBy(keySelector, elementSelector);
530         List<R> resultList = new ArrayList<R>();
531 
532         for (Entry<K, List<E>> entry : map.entrySet()) {
533             resultList.add(resultSelector.call(entry.getKey(),
534                     new BasicEnumerable<E>(entry.getValue())));
535         }
536 
537         return new BasicEnumerable<R>(resultList);
538     }
539 
540     private <E, K> LinkedHashMap<K, List<E>> doGroupBy(Func<T, K> keySelector,
541             Func<T, E> elementSelector) {
542 
543         LinkedHashMap<K, List<E>> map = new LinkedHashMap<K, List<E>>();
544 
545         for (T entity : iterable) {
546             K key = keySelector.call(entity);
547             List<E> list = map.get(key);
548 
549             if (list == null) {
550                 list = new ArrayList<E>();
551                 map.put(key, list);
552             }
553 
554             list.add(elementSelector.call(entity));
555         }
556 
557         return map;
558     }
559 
560     public <I, K, R> Enumerable<R> groupJoin(final Enumerable<I> inner,
561             final Func<T, K> outerKeySelector,
562             final Func<I, K> innerKeySelector,
563             final Func2<T, Enumerable<I>, R> resultSelector) {
564 
565         return new BasicEnumerable<R>(new Iterable<R>() {
566 
567             public Iterator<R> iterator() {
568 
569                 return new Iterator<R>() {
570 
571                     private final Iterator<T> iterator = iterable.iterator();
572 
573                     private final Map<K, List<I>> innerListMap;
574 
575                     {
576                         innerListMap = new HashMap<K, List<I>>();
577 
578                         for (I innerEntity : inner) {
579                             K innerKey = innerKeySelector.call(innerEntity);
580                             List<I> innerList = innerListMap.get(innerKey);
581 
582                             if (innerList == null) {
583                                 innerList = new ArrayList<I>();
584                                 innerListMap.put(innerKey, innerList);
585                             }
586 
587                             innerList.add(innerEntity);
588                         }
589                     }
590 
591                     public boolean hasNext() {
592                         return iterator.hasNext();
593                     }
594 
595                     public R next() {
596                         T outerEntity = iterator.next();
597                         K outerKey = outerKeySelector.call(outerEntity);
598                         List<I> innerList = innerListMap.get(outerKey);
599                         return resultSelector.call(outerEntity,
600                                 new BasicEnumerable<I>(innerList));
601                     }
602 
603                     public void remove() {
604                         throw new UnsupportedOperationException();
605                     }
606                 };
607             }
608         });
609     }
610 
611     public Enumerable<T> intersect(final Enumerable<T> second) {
612         return new BasicEnumerable<T>(new Iterable<T>() {
613 
614             public Iterator<T> iterator() {
615                 return new QueuedIterator<T, T, T>(iterable.iterator()) {
616 
617                     private final Set<T> firstSet = new HashSet<T>();
618 
619                     private final Set<T> secondSet = new HashSet<T>(second
620                             .toList());
621 
622                     @Override
623                     protected void addElement(Queue<T> queue, T t) {
624 
625                         if (secondSet.contains(t) && !firstSet.contains(t)) {
626                             queue.add(t);
627                             firstSet.add(t);
628                         }
629                     }
630 
631                     @Override
632                     protected T toResult(T e) {
633                         return e;
634                     }
635                 };
636             }
637         });
638     }
639 
640     public <I, K, R> Enumerable<R> join(final Enumerable<I> inner,
641             final Func<T, K> outerKeySelector,
642             final Func<I, K> innerKeySelector,
643             final Func2<T, I, R> resultSelector) {
644 
645         return new BasicEnumerable<R>(new Iterable<R>() {
646 
647             public Iterator<R> iterator() {
648                 return new QueuedIterator<T, Pair<T, I>, R>(iterable.iterator()) {
649 
650                     private final Map<K, I> innerMap;
651 
652                     {
653                         innerMap = new HashMap<K, I>();
654 
655                         for (I innerEntity : inner) {
656                             K innerKey = innerKeySelector.call(innerEntity);
657                             innerMap.put(innerKey, innerEntity);
658                         }
659                     }
660 
661                     @Override
662                     protected void addElement(Queue<Pair<T, I>> queue, T t) {
663                         K outerKey = outerKeySelector.call(t);
664                         I innerEntity = innerMap.get(outerKey);
665 
666                         if (innerEntity != null) {
667                             queue.add(new Pair<T, I>(t, innerEntity));
668                         }
669                     }
670 
671                     @Override
672                     protected R toResult(Pair<T, I> e) {
673                         return resultSelector.call(e.a, e.b);
674                     }
675                 };
676             }
677         });
678     }
679 
680     public T last() {
681         Iterator<T> iterator = iterable.iterator();
682 
683         if (!iterator.hasNext()) {
684             throw new NoSuchElementException();
685         }
686 
687         T last = null;
688 
689         while (iterator.hasNext()) {
690             last = iterator.next();
691         }
692 
693         return last;
694     }
695 
696     public T last(Func<T, Boolean> predicate) {
697         T last = null;
698         boolean found = false;
699 
700         for (T t : iterable) {
701 
702             if (predicate.call(t)) {
703                 last = t;
704 
705                 if (!found) {
706                     found = true;
707                 }
708             }
709         }
710 
711         if (!found) {
712             throw new NoSuchElementException();
713         }
714 
715         return last;
716     }
717 
718     public T lastOrDefault() {
719         return lastOrDefault((T) null);
720     }
721 
722     public T lastOrDefault(T defaultValue) {
723         Iterator<T> iterator = iterable.iterator();
724 
725         if (!iterator.hasNext()) {
726             return defaultValue;
727         }
728 
729         T last = null;
730 
731         while (iterator.hasNext()) {
732             last = iterator.next();
733         }
734 
735         return last;
736     }
737 
738     public T lastOrDefault(Func<T, Boolean> predicate) {
739         return lastOrDefault(predicate, null);
740     }
741 
742     public T lastOrDefault(Func<T, Boolean> predicate, T defaultValue) {
743         T last = null;
744         boolean found = false;
745 
746         for (T t : iterable) {
747 
748             if (predicate.call(t)) {
749                 last = t;
750 
751                 if (!found) {
752                     found = true;
753                 }
754             }
755         }
756 
757         if (!found) {
758             return defaultValue;
759         }
760 
761         return last;
762     }
763 
764     public long longCount() {
765         long c = 0;
766 
767         for (Iterator<T> it = iterable.iterator(); it.hasNext(); it.next()) {
768             c++;
769         }
770 
771         return c;
772     }
773 
774     public long longCount(Func<T, Boolean> predicate) {
775         long c = 0;
776 
777         for (T t : iterable) {
778 
779             if (predicate.call(t)) {
780                 c++;
781             }
782         }
783 
784         return c;
785     }
786 
787     @SuppressWarnings("unchecked")
788     public T max() {
789         Iterator<T> iterator = iterable.iterator();
790         T max = iterator.next();
791 
792         while (iterator.hasNext()) {
793             T t = iterator.next();
794 
795             if (((Comparable<T>) t).compareTo(max) > 0) {
796                 max = t;
797             }
798         }
799 
800         return max;
801     }
802 
803     public <R extends Comparable<R>> R max(Func<T, R> selector) {
804         Iterator<T> iterator = iterable.iterator();
805         R max = selector.call(iterator.next());
806 
807         while (iterator.hasNext()) {
808             R r = selector.call(iterator.next());
809 
810             if (r.compareTo(max) > 0) {
811                 max = r;
812             }
813         }
814 
815         return max;
816     }
817 
818     @SuppressWarnings("unchecked")
819     public T min() {
820         Iterator<T> iterator = iterable.iterator();
821         T min = iterator.next();
822 
823         while (iterator.hasNext()) {
824             T t = iterator.next();
825 
826             if (((Comparable<T>) t).compareTo(min) < 0) {
827                 min = t;
828             }
829         }
830 
831         return min;
832     }
833 
834     public <R extends Comparable<R>> R min(Func<T, R> selector) {
835         Iterator<T> iterator = iterable.iterator();
836         R min = selector.call(iterator.next());
837 
838         while (iterator.hasNext()) {
839             R r = selector.call(iterator.next());
840 
841             if (r.compareTo(min) < 0) {
842                 min = r;
843             }
844         }
845 
846         return min;
847     }
848 
849     public <R> Enumerable<R> ofType(final Class<R> resultClass) {
850         return new BasicEnumerable<R>(new Iterable<R>() {
851 
852             public Iterator<R> iterator() {
853                 return new QueuedIterator<T, T, R>(iterable.iterator()) {
854 
855                     @Override
856                     protected void addElement(Queue<T> queue, T t) {
857 
858                         if (resultClass.isInstance(t)) {
859                             queue.add(t);
860                         }
861                     }
862 
863                     @Override
864                     protected R toResult(T e) {
865                         return resultClass.cast(e);
866                     }
867                 };
868             }
869         });
870     }
871 
872     public <K> OrderedEnumerable<T> orderBy(Func<T, K> keySelector) {
873         return new BasicOrderedEnumerable<T>(this, keySelector, false);
874     }
875 
876     public <K> OrderedEnumerable<T> orderBy(Func<T, K> keySelector,
877             Comparator<K> comparator) {
878 
879         return new BasicOrderedEnumerable<T>(this, keySelector, false,
880                 comparator);
881     }
882 
883     public <K> OrderedEnumerable<T> orderByDescending(Func<T, K> keySelector) {
884         return new BasicOrderedEnumerable<T>(this, keySelector, true);
885     }
886 
887     public <K> OrderedEnumerable<T> orderByDescending(Func<T, K> keySelector,
888             Comparator<K> comparator) {
889 
890         return new BasicOrderedEnumerable<T>(this, keySelector, true,
891                 comparator);
892     }
893 
894     public static Enumerable<Integer> range(final int start, final int count) {
895         return new BasicEnumerable<Integer>(new Iterable<Integer>() {
896 
897             public Iterator<Integer> iterator() {
898 
899                 return new Iterator<Integer>() {
900 
901                     private int index;
902 
903                     private int value = start;
904 
905                     public boolean hasNext() {
906                         return index < count;
907                     }
908 
909                     public Integer next() {
910 
911                         if (index >= count) {
912                             throw new NoSuchElementException();
913                         }
914 
915                         index++;
916                         return value++;
917                     }
918 
919                     public void remove() {
920                         throw new UnsupportedOperationException();
921                     }
922                 };
923             }
924         });
925     }
926 
927     public static <R> Enumerable<R> repeat(final R element, final int count) {
928         return new BasicEnumerable<R>(new Iterable<R>() {
929 
930             public Iterator<R> iterator() {
931 
932                 return new Iterator<R>() {
933 
934                     private int index;
935 
936                     public boolean hasNext() {
937                         return index < count;
938                     }
939 
940                     public R next() {
941 
942                         if (index >= count) {
943                             throw new NoSuchElementException();
944                         }
945 
946                         index++;
947                         return element;
948                     }
949 
950                     public void remove() {
951                         throw new UnsupportedOperationException();
952                     }
953                 };
954             }
955         });
956     }
957 
958     public Enumerable<T> reverse() {
959         List<T> list = toList();
960         Collections.reverse(list);
961         return new BasicEnumerable<T>(list);
962     }
963 
964     public <R> Enumerable<R> select(final Func<T, R> selector) {
965         return new BasicEnumerable<R>(new Iterable<R>() {
966 
967             public Iterator<R> iterator() {
968 
969                 return new Iterator<R>() {
970 
971                     private final Iterator<T> iterator = iterable.iterator();
972 
973                     public boolean hasNext() {
974                         return iterator.hasNext();
975                     }
976 
977                     public R next() {
978                         return selector.call(iterator.next());
979                     }
980 
981                     public void remove() {
982                         throw new UnsupportedOperationException();
983                     }
984                 };
985             }
986         });
987     }
988 
989     public <R> Enumerable<R> select(final Func2<T, Integer, R> selector) {
990         return select(new Func<T, R>() {
991 
992             private int index;
993 
994             public R call(T arg1) {
995                 return selector.call(arg1, index++);
996             }
997         });
998     }
999 
1000     public <R> Enumerable<R> selectMany(Func<T, Enumerable<R>> selector) {
1001         return selectMany(selector, new Func2<T, R, R>() {
1002 
1003             public R call(T arg1, R arg2) {
1004                 return arg2;
1005             }
1006         });
1007     }
1008 
1009     public <C, R> Enumerable<R> selectMany(
1010             final Func<T, Enumerable<C>> collectionSelector,
1011             final Func2<T, C, R> resultSelector) {
1012 
1013         return new BasicEnumerable<R>(new Iterable<R>() {
1014 
1015             public Iterator<R> iterator() {
1016                 return new QueuedIterator<T, Pair<T, C>, R>(iterable.iterator()) {
1017 
1018                     @Override
1019                     protected void addElement(Queue<Pair<T, C>> queue, T t) {
1020 
1021                         for (C c : collectionSelector.call(t)) {
1022                             queue.add(new Pair<T, C>(t, c));
1023                         }
1024                     }
1025 
1026                     @Override
1027                     protected R toResult(Pair<T, C> e) {
1028                         return resultSelector.call(e.a, e.b);
1029                     }
1030                 };
1031             }
1032         });
1033     }
1034 
1035     public <R> Enumerable<R> selectMany(
1036             Func2<T, Integer, Enumerable<R>> selector) {
1037 
1038         return selectMany(selector, new Func2<T, R, R>() {
1039 
1040             public R call(T arg1, R arg2) {
1041                 return arg2;
1042             }
1043         });
1044     }
1045 
1046     public <C, R> Enumerable<R> selectMany(
1047             final Func2<T, Integer, Enumerable<C>> collectionSelector,
1048             Func2<T, C, R> resultSelector) {
1049 
1050         return selectMany(new Func<T, Enumerable<C>>() {
1051 
1052             private int index;
1053 
1054             public Enumerable<C> call(T arg1) {
1055                 return collectionSelector.call(arg1, index++);
1056             }
1057         }, resultSelector);
1058     }
1059 
1060     public Boolean sequenceEqual(Enumerable<T> second) {
1061         Iterator<T> iterator = second.iterator();
1062 
1063         for (T f : iterable) {
1064 
1065             if (!iterator.hasNext()) {
1066                 return false;
1067             }
1068 
1069             if (!equals(f, iterator.next())) {
1070                 return false;
1071             }
1072         }
1073 
1074         if (iterator.hasNext()) {
1075             return false;
1076         }
1077 
1078         return true;
1079     }
1080 
1081     public T single() {
1082         Iterator<T> iterator = iterable.iterator();
1083         T t = iterator.next();
1084 
1085         if (iterator.hasNext()) {
1086             throw new NoSuchElementException();
1087         }
1088 
1089         return t;
1090     }
1091 
1092     public T single(Func<T, Boolean> predicate) {
1093         T single = null;
1094         boolean found = false;
1095 
1096         for (T t : iterable) {
1097 
1098             if (predicate.call(t)) {
1099 
1100                 if (found) {
1101                     found = false;
1102                     break;
1103                 }
1104 
1105                 single = t;
1106                 found = true;
1107             }
1108         }
1109 
1110         if (!found) {
1111             throw new NoSuchElementException();
1112         }
1113 
1114         return single;
1115     }
1116 
1117     public T singleOrDefault() {
1118         return singleOrDefault((T) null);
1119     }
1120 
1121     public T singleOrDefault(T defaultValue) {
1122         Iterator<T> iterator = iterable.iterator();
1123 
1124         if (!iterator.hasNext()) {
1125             return defaultValue;
1126         }
1127 
1128         T t = iterator.next();
1129 
1130         if (iterator.hasNext()) {
1131             return defaultValue;
1132         }
1133 
1134         return t;
1135     }
1136 
1137     public T singleOrDefault(Func<T, Boolean> predicate) {
1138         return singleOrDefault(predicate, (T) null);
1139     }
1140 
1141     public T singleOrDefault(Func<T, Boolean> predicate, T defaultValue) {
1142         T single = null;
1143         boolean found = false;
1144 
1145         for (T t : iterable) {
1146 
1147             if (predicate.call(t)) {
1148 
1149                 if (found) {
1150                     found = false;
1151                     break;
1152                 }
1153 
1154                 single = t;
1155                 found = true;
1156             }
1157         }
1158 
1159         if (!found) {
1160             return defaultValue;
1161         }
1162 
1163         return single;
1164     }
1165 
1166     public Enumerable<T> skip(final int count) {
1167         return new BasicEnumerable<T>(new Iterable<T>() {
1168 
1169             public Iterator<T> iterator() {
1170                 return new Iterator<T>() {
1171 
1172                     private final Iterator<T> iterator = iterable.iterator();
1173 
1174                     private boolean skipped;
1175 
1176                     private boolean skip() {
1177 
1178                         if (skipped) {
1179                             return true;
1180                         }
1181 
1182                         skipped = true;
1183 
1184                         for (int i = 0; i < count; i++) {
1185 
1186                             if (!iterator.hasNext()) {
1187                                 return false;
1188                             }
1189 
1190                             iterator.next();
1191                         }
1192 
1193                         return true;
1194                     }
1195 
1196                     public boolean hasNext() {
1197 
1198                         if (!skip()) {
1199                             return false;
1200                         }
1201 
1202                         return iterator.hasNext();
1203                     }
1204 
1205                     public T next() {
1206 
1207                         if (!skip()) {
1208                             throw new NoSuchElementException();
1209                         }
1210 
1211                         return iterator.next();
1212                     }
1213 
1214                     public void remove() {
1215                         throw new UnsupportedOperationException();
1216                     }
1217                 };
1218             }
1219         });
1220     }
1221 
1222     public Enumerable<T> skipWhile(final Func<T, Boolean> predicate) {
1223         return new BasicEnumerable<T>(new Iterable<T>() {
1224 
1225             public Iterator<T> iterator() {
1226                 return new QueuedIterator<T, T, T>(iterable.iterator()) {
1227 
1228                     private boolean skipped;
1229 
1230                     @Override
1231                     protected void addElement(Queue<T> queue, T t) {
1232 
1233                         if (!skipped) {
1234 
1235                             if (predicate.call(t)) {
1236                                 return;
1237                             }
1238 
1239                             skipped = true;
1240                         }
1241 
1242                         queue.add(t);
1243                     }
1244 
1245                     @Override
1246                     protected T toResult(T e) {
1247                         return e;
1248                     }
1249                 };
1250             }
1251         });
1252     }
1253 
1254     public Enumerable<T> skipWhile(final Func2<T, Integer, Boolean> predicate) {
1255         return skipWhile(new Func<T, Boolean>() {
1256 
1257             private int index;
1258 
1259             public Boolean call(T arg1) {
1260                 return predicate.call(arg1, index++);
1261             }
1262         });
1263     }
1264 
1265     public int sum() {
1266         int sum = 0;
1267 
1268         for (T t : iterable) {
1269             sum += (Integer) t;
1270         }
1271 
1272         return sum;
1273     }
1274 
1275     public long sumLong() {
1276         long sum = 0;
1277 
1278         for (T t : iterable) {
1279             sum += (Long) t;
1280         }
1281 
1282         return sum;
1283     }
1284 
1285     public float sumFloat() {
1286         float sum = 0;
1287 
1288         for (T t : iterable) {
1289             sum += (Float) t;
1290         }
1291 
1292         return sum;
1293     }
1294 
1295     public double sumDouble() {
1296         double sum = 0;
1297 
1298         for (T t : iterable) {
1299             sum += (Double) t;
1300         }
1301 
1302         return sum;
1303     }
1304 
1305     public int sum(Func<T, Integer> selector) {
1306         int sum = 0;
1307 
1308         for (T t : iterable) {
1309             sum += selector.call(t);
1310         }
1311 
1312         return sum;
1313     }
1314 
1315     public long sumLong(Func<T, Long> selector) {
1316         long sum = 0;
1317 
1318         for (T t : iterable) {
1319             sum += selector.call(t);
1320         }
1321 
1322         return sum;
1323     }
1324 
1325     public float sumFloat(Func<T, Float> selector) {
1326         float sum = 0;
1327 
1328         for (T t : iterable) {
1329             sum += selector.call(t);
1330         }
1331 
1332         return sum;
1333     }
1334 
1335     public double sumDouble(Func<T, Double> selector) {
1336         double sum = 0;
1337 
1338         for (T t : iterable) {
1339             sum += selector.call(t);
1340         }
1341 
1342         return sum;
1343     }
1344 
1345     public Enumerable<T> take(final int count) {
1346         return new BasicEnumerable<T>(new Iterable<T>() {
1347 
1348             public Iterator<T> iterator() {
1349                 return new Iterator<T>() {
1350 
1351                     private final Iterator<T> iterator = iterable.iterator();
1352 
1353                     private int index;
1354 
1355                     public boolean hasNext() {
1356 
1357                         if (index >= count) {
1358                             return false;
1359                         }
1360 
1361                         return iterator.hasNext();
1362                     }
1363 
1364                     public T next() {
1365 
1366                         if (index >= count) {
1367                             throw new NoSuchElementException();
1368                         }
1369 
1370                         index++;
1371                         return iterator.next();
1372                     }
1373 
1374                     public void remove() {
1375                         throw new UnsupportedOperationException();
1376                     }
1377                 };
1378             }
1379         });
1380     }
1381 
1382     public Enumerable<T> takeWhile(final Func<T, Boolean> predicate) {
1383         return new BasicEnumerable<T>(new Iterable<T>() {
1384 
1385             public Iterator<T> iterator() {
1386                 return new QueuedIterator<T, T, T>(iterable.iterator()) {
1387 
1388                     private boolean done;
1389 
1390                     @Override
1391                     protected void addElement(Queue<T> queue, T t) {
1392 
1393                         if (done) {
1394                             return;
1395                         }
1396 
1397                         if (!predicate.call(t)) {
1398                             done = true;
1399                             return;
1400                         }
1401 
1402                         queue.add(t);
1403                     }
1404 
1405                     @Override
1406                     protected T toResult(T e) {
1407                         return e;
1408                     }
1409                 };
1410             }
1411         });
1412     }
1413 
1414     public Enumerable<T> takeWhile(final Func2<T, Integer, Boolean> predicate) {
1415         return takeWhile(new Func<T, Boolean>() {
1416 
1417             private int index;
1418 
1419             public Boolean call(T arg1) {
1420                 return predicate.call(arg1, index++);
1421             }
1422         });
1423     }
1424 
1425     public Object[] toArray() {
1426         return toList().toArray();
1427     }
1428 
1429     @SuppressWarnings("unchecked")
1430     public <R> R[] toArray(Class<R> resultClass) {
1431         List<T> list = toList();
1432         R[] array = (R[]) Array.newInstance(resultClass, list.size());
1433         return list.toArray(array);
1434     }
1435 
1436     public List<T> toList() {
1437         ArrayList<T> list = new ArrayList<T>();
1438 
1439         for (T e : iterable) {
1440             list.add(e);
1441         }
1442 
1443         return list;
1444     }
1445 
1446     public EnumerableList<T> toEnumerableList() {
1447         return new BasicEnumerableList<T>(toList());
1448     }
1449 
1450     public <K> Map<K, List<T>> toListMap(Func<T, K> keySelector) {
1451         return toListMap(keySelector, getPassThroughFunc());
1452     }
1453 
1454     public <K, E> Map<K, List<E>> toListMap(Func<T, K> keySelector,
1455             Func<T, E> elementSelector) {
1456 
1457         Map<K, List<E>> map = new LinkedHashMap<K, List<E>>();
1458 
1459         for (T t : iterable) {
1460             K k = keySelector.call(t);
1461             List<E> list = map.get(k);
1462 
1463             if (list == null) {
1464                 list = new ArrayList<E>();
1465                 map.put(k, list);
1466             }
1467 
1468             list.add(elementSelector.call(t));
1469         }
1470 
1471         return map;
1472     }
1473 
1474     public <K> Lookup<K, T> toLookup(Func<T, K> keySelector) {
1475         return toLookup(keySelector, getPassThroughFunc());
1476     }
1477 
1478     public <K, E> Lookup<K, E> toLookup(Func<T, K> keySelector,
1479             Func<T, E> elementSelector) {
1480 
1481         return new BasicLookup<K, E>(toListMap(keySelector, elementSelector));
1482     }
1483 
1484     public <K> Map<K, T> toMap(Func<T, K> keySelector) {
1485         return toMap(keySelector, getPassThroughFunc());
1486     }
1487 
1488     public <K, E> Map<K, E> toMap(Func<T, K> keySelector,
1489             Func<T, E> elementSelector) {
1490 
1491         Map<K, E> map = new LinkedHashMap<K, E>();
1492 
1493         for (T t : iterable) {
1494             K k = keySelector.call(t);
1495 
1496             if (map.containsKey(k)) {
1497                 throw new IllegalArgumentException();
1498             }
1499 
1500             map.put(k, elementSelector.call(t));
1501         }
1502 
1503         return map;
1504     }
1505 
1506     public <K> Dictionary<K, T> toDictionary(Func<T, K> keySelector) {
1507         return toDictionary(keySelector, getPassThroughFunc());
1508     }
1509 
1510     public <K, E> Dictionary<K, E> toDictionary(Func<T, K> keySelector,
1511             Func<T, E> elementSelector) {
1512 
1513         return new BasicDictionary<K, E>(toMap(keySelector, elementSelector));
1514     }
1515 
1516     public Enumerable<T> union(final Enumerable<T> second) {
1517         return new BasicEnumerable<T>(new Iterable<T>() {
1518 
1519             public Iterator<T> iterator() {
1520                 return new QueuedIterator<T, T, T>(new ConcatenatedIterator<T>(
1521                         iterable.iterator(), second.iterator())) {
1522 
1523                     private final Set<T> set = new HashSet<T>();
1524 
1525                     @Override
1526                     protected void addElement(Queue<T> queue, T t) {
1527 
1528                         if (!set.contains(t)) {
1529                             queue.add(t);
1530                             set.add(t);
1531                         }
1532                     }
1533 
1534                     @Override
1535                     protected T toResult(T e) {
1536                         return e;
1537                     }
1538                 };
1539             }
1540         });
1541     }
1542 
1543     public Enumerable<T> where(final Func<T, Boolean> predicate) {
1544         return new BasicEnumerable<T>(new Iterable<T>() {
1545 
1546             public Iterator<T> iterator() {
1547                 return new QueuedIterator<T, T, T>(iterable.iterator()) {
1548 
1549                     @Override
1550                     protected void addElement(Queue<T> queue, T t) {
1551 
1552                         if (predicate.call(t)) {
1553                             queue.add(t);
1554                         }
1555                     }
1556 
1557                     @Override
1558                     protected T toResult(T e) {
1559                         return e;
1560                     }
1561                 };
1562             }
1563         });
1564     }
1565 
1566     public Enumerable<T> where(final Func2<T, Integer, Boolean> predicate) {
1567         return where(new Func<T, Boolean>() {
1568 
1569             private int index;
1570 
1571             public Boolean call(T arg1) {
1572                 return predicate.call(arg1, index++);
1573             }
1574         });
1575     }
1576 
1577     private Func<T, T> getPassThroughFunc() {
1578         return new Func<T, T>() {
1579 
1580             public T call(T arg1) {
1581                 return arg1;
1582             }
1583         };
1584     }
1585 }