aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/zwobble/couscous/util/ExtraIterables.java
blob: 1fd9fca3b8a35ddc2e99749459e36c4dbe91169c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package org.zwobble.couscous.util;

import java.util.Iterator;
import java.util.function.BiFunction;

public class ExtraIterables {
    private ExtraIterables() {}

    public static <T, U> void forEach(Iterable<? extends T> first, Iterable<? extends U> second, Action2<T, U> action) {
        Iterator<? extends T> firstIterator = first.iterator();
        Iterator<? extends U> secondIterator = second.iterator();
        while (firstIterator.hasNext()) {
            action.run(firstIterator.next(), secondIterator.next());
        }
        if (secondIterator.hasNext()) {
            throw new RuntimeException("Iterables not of same length");
        }
    }

    public static <T1, T2, R> Iterable<R> map(Iterable<T1> iterable1, Iterable<T2> iterable2, BiFunction<T1, T2, R> function) {
        return new Iterable<R>() {
            @Override
            public Iterator<R> iterator() {
                Iterator<T1> iterator1 = iterable1.iterator();
                Iterator<T2> iterator2 = iterable2.iterator();
                return map(iterator1, iterator2, function);
            }
        };
    }

    private static <R, T1, T2> Iterator<R> map(Iterator<T1> iterator1, Iterator<T2> iterator2, BiFunction<T1, T2, R> function) {
        return new Iterator<R>() {
            @Override
            public boolean hasNext() {
                return iterator1.hasNext() && iterator2.hasNext();
            }

            @Override
            public R next() {
                return function.apply(iterator1.next(), iterator2.next());
            }
        };
    }

    public static <T> Iterable<T> cast(Class<T> type, Iterable<?> iterable) {
        return new Iterable<T>() {
            @Override
            public Iterator<T> iterator() {
                return cast(type, iterable.iterator());
            }
        };
    }

    private static <T> Iterator<T> cast(Class<T> type, Iterator<?> iterator) {
        return new Iterator<T>() {
            @Override
            public boolean hasNext() {
                return iterator.hasNext();
            }

            @Override
            public T next() {
                Object next = iterator.next();
                if (type.isInstance(next)) {
                    return (T) next;
                } else {
                    throw new ClassCastException();
                }
            }
        };
    }
}