/******************************************************************************* * Copyright 2011 See AUTHORS file. * * 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 com.badlogic.gdx.utils; import java.util.Iterator; import com.badlogic.gdx.utils.Array.ArrayIterator; /** Interface used to select items within an iterator against a predicate. * @author Xoppa */ public interface Predicate<T> { /** @return true if the item matches the criteria and should be included in the iterator's items */ boolean evaluate (T arg0); public class PredicateIterator<T> implements Iterator<T> { public Iterator<T> iterator; public Predicate<T> predicate; public boolean end = false; public boolean peeked = false; public T next = null; public PredicateIterator (final Iterable<T> iterable, final Predicate<T> predicate) { this(iterable.iterator(), predicate); } public PredicateIterator (final Iterator<T> iterator, final Predicate<T> predicate) { set(iterator, predicate); } public void set (final Iterable<T> iterable, final Predicate<T> predicate) { set(iterable.iterator(), predicate); } public void set (final Iterator<T> iterator, final Predicate<T> 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 GdxRuntimeException("Cannot remove between a call to hasNext() and next()."); iterator.remove(); } } public static class PredicateIterable<T> implements Iterable<T> { public Iterable<T> iterable; public Predicate<T> predicate; public PredicateIterator<T> iterator = null; public PredicateIterable (Iterable<T> iterable, Predicate<T> predicate) { set(iterable, predicate); } public void set (Iterable<T> iterable, Predicate<T> 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<T> iterator () { if (iterator == null) iterator = new PredicateIterator<T>(iterable.iterator(), predicate); else iterator.set(iterable.iterator(), predicate); return iterator; } } }