package io.dico.dicore.task; import java.util.*; import java.util.function.BiConsumer; import java.util.function.BiPredicate; import java.util.function.Consumer; import java.util.function.Predicate; public abstract class IteratorTask extends BaseTask { private Iterator iterator; public IteratorTask() { } @SuppressWarnings("unchecked") public IteratorTask(Iterable iterable, boolean clone) { refresh(iterable, clone); } public IteratorTask(Iterable iterable) { this(iterable, false); } public IteratorTask(Iterator iterator) { refresh(iterator); } @Override protected void doStartChecks() { super.doStartChecks(); if (iterator == null) { throw new IllegalStateException("An iterator must be supplied first"); } } protected final void refresh(Iterable iterable, boolean clone) { if (clone) { Collection collection; if (!(iterable instanceof Collection)) { collection = new LinkedList<>(); for (T next : iterable) { collection.add(next); } } else { collection = new ArrayList((Collection) iterable); } iterator = collection.iterator(); } else { iterator = iterable.iterator(); } } protected final void refresh(Iterator iterator) { Objects.requireNonNull(iterator); this.iterator = iterator; } @Override protected T supply() { return iterator.next(); } protected void remove() { iterator.remove(); } // One argument: The processed object public static IteratorTask create(Iterable iterable, Consumer processor) { return create(iterable, false, processor); } public static IteratorTask create(Iterable iterable, boolean clone, Consumer processor) { return create(iterable, clone, object -> { processor.accept(object); return true; }); } public static IteratorTask create(Iterable iterable, Predicate processor) { return create(iterable, false, processor); } public static IteratorTask create(Iterable iterable, boolean clone, Predicate processor) { return new IteratorTask(iterable, clone) { @Override protected boolean process(T object) { return processor.test(object); } }; } // Two arguments: the processed object, and a runnable to remove it from the iterator. public static IteratorTask create(Iterable iterable, BiConsumer processor) { return create(iterable, false, processor); } public static IteratorTask create(Iterable iterable, boolean clone, BiConsumer processor) { return create(iterable, clone, (object, runnable) -> { processor.accept(object, runnable); return true; }); } public static IteratorTask create(Iterable iterable, BiPredicate processor) { return create(iterable, false, processor); } public static IteratorTask create(Iterable iterable, boolean clone, BiPredicate processor) { return new IteratorTask(iterable, clone) { @Override protected boolean process(T object) { return processor.test(object, this::remove); } }; } }