package org.zwobble.mammoth.internal.util; import java.util.Iterator; import java.util.Optional; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Stream; import java.util.stream.StreamSupport; public class Iterables { public static Optional tryFind(Iterable iterable, Predicate predicate) { for (T element : iterable) { if (predicate.test(element)) { return Optional.of(element); } } return Optional.empty(); } public static Iterable lazyMap(Iterable iterable, Function function) { return new Iterable() { @Override public Iterator iterator() { return map(iterable.iterator(), function); } }; } public static Optional getFirst(Iterable iterable) { Iterator iterator = iterable.iterator(); if (iterator.hasNext()) { return Optional.of(iterator.next()); } else { return Optional.empty(); } } public static T getFirst(Iterable iterable, T defaultValue) { Iterator iterator = iterable.iterator(); if (iterator.hasNext()) { return iterator.next(); } else { return defaultValue; } } public static Iterable lazyFlatMap(Iterable iterable, Function> function) { return lazyFlatten(lazyMap(iterable, function)); } public static Iterable lazyConcat(Iterable iterable1, Iterable iterable2) { return new Iterable() { @Override public Iterator iterator() { return Stream.concat(stream(iterable1), stream(iterable2)).iterator(); } }; } public static Iterable lazyFlatten(Iterable> iterables) { return new Iterable() { @Override public Iterator iterator() { return stream(iterables) .flatMap(iterable -> stream(iterable)) .iterator(); } }; } public static Iterable lazyFilter(Iterable iterables, Predicate predicate) { return new Iterable() { @Override public Iterator iterator() { return stream(iterables) .filter(predicate) .iterator(); } }; } public static Iterable lazyFilter(Iterable iterables, Class clazz) { return new Iterable() { @Override @SuppressWarnings("unchecked") public Iterator iterator() { return (Iterator) stream(iterables) .filter(clazz::isInstance) .iterator(); } }; } private static Iterator map(Iterator iterator, Function function) { return new Iterator() { @Override public boolean hasNext() { return iterator.hasNext(); } @Override public R next() { return function.apply(iterator.next()); } }; } public static boolean any(Iterable iterable, Predicate predicate) { return stream(iterable).anyMatch(predicate); } public static Stream stream(Iterable iterable) { return StreamSupport.stream(iterable.spliterator(), false); } }