/******************************************************************************* * Copyright 2011 LibGDX. * Mario Zechner * Nathan Sweet * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package dorkbox.collections; import java.util.Iterator; /** Interface used to select items within an iterator against a predicate. * @author Xoppa */ public interface Predicate { /** @return true if the item matches the criteria and should be included in the iterator's items */ boolean evaluate (T arg0); public class PredicateIterator implements Iterator { public Iterator iterator; public Predicate predicate; public boolean end = false; public boolean peeked = false; public T next = null; public PredicateIterator (final Iterable iterable, final Predicate predicate) { this(iterable.iterator(), predicate); } public PredicateIterator (final Iterator iterator, final Predicate predicate) { set(iterator, predicate); } public void set (final Iterable iterable, final Predicate predicate) { set(iterable.iterator(), predicate); } public void set (final Iterator iterator, final Predicate predicate) { this.iterator = iterator; this.predicate = predicate; end = peeked = false; next = null; } @Override public boolean hasNext () { if (end) return false; if (next != null) return true; peeked = true; while (iterator.hasNext()) { final T n = iterator.next(); if (predicate.evaluate(n)) { next = n; return true; } } end = true; return false; } @Override public T next () { if (next == null && !hasNext()) return null; final T result = next; next = null; peeked = false; return result; } @Override public void remove () { if (peeked) throw new RuntimeException("Cannot remove between a call to hasNext() and next()."); iterator.remove(); } } public static class PredicateIterable implements Iterable { public Iterable iterable; public Predicate predicate; public PredicateIterator iterator = null; public PredicateIterable (Iterable iterable, Predicate predicate) { set(iterable, predicate); } public void set (Iterable iterable, Predicate predicate) { this.iterable = iterable; this.predicate = predicate; } /** Returns an iterator. Note that the same iterator instance is returned each time this method is called. Use the * {@link Predicate.PredicateIterator} constructor for nested or multithreaded iteration. */ @Override public Iterator iterator () { if (iterator == null) iterator = new PredicateIterator(iterable.iterator(), predicate); else iterator.set(iterable.iterator(), predicate); return iterator; } } }