001/** 002 * Copyright (c) 2011, The University of Southampton and the individual contributors. 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without modification, 006 * are permitted provided that the following conditions are met: 007 * 008 * * Redistributions of source code must retain the above copyright notice, 009 * this list of conditions and the following disclaimer. 010 * 011 * * Redistributions in binary form must reproduce the above copyright notice, 012 * this list of conditions and the following disclaimer in the documentation 013 * and/or other materials provided with the distribution. 014 * 015 * * Neither the name of the University of Southampton nor the names of its 016 * contributors may be used to endorse or promote products derived from this 017 * software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030package org.openimaj.util.filter; 031 032import java.util.ArrayList; 033import java.util.Collection; 034import java.util.Iterator; 035 036import org.openimaj.util.array.ArrayIterator; 037import org.openimaj.util.function.Predicate; 038 039/** 040 * Utilities for filtering collections by applying a {@link Predicate}. 041 * 042 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk) 043 */ 044public class FilterUtils { 045 private FilterUtils() { 046 } 047 048 /** 049 * Filter a collection, returning the accepted items in an {@link ArrayList} 050 * . 051 * 052 * @see Predicate#test(Object) 053 * 054 * @param <T> 055 * type of object being filtered 056 * @param <Q> 057 * type of object accepted by the filter 058 * @param in 059 * input collection 060 * @param filter 061 * the filter 062 * @return the list of accepted items 063 */ 064 public static <T, Q extends T> ArrayList<Q> filter(final Collection<Q> in, final Predicate<T> filter) { 065 final ArrayList<Q> out = new ArrayList<Q>(); 066 067 for (final Q item : in) 068 if (filter.test(item)) 069 out.add(item); 070 071 return out; 072 } 073 074 /** 075 * Filter a collection, storing the accepted items in the given output 076 * collection. 077 * 078 * @see Predicate#test(Object) 079 * 080 * @param <T> 081 * type of object being filtered 082 * @param in 083 * input collection 084 * @param out 085 * output collection 086 * @param filter 087 * the filter 088 * @return the list of accepted items 089 */ 090 public static <T> Collection<T> filter(final Collection<? extends T> in, final Collection<T> out, 091 final Predicate<T> filter) 092 { 093 for (final T item : in) 094 if (filter.test(item)) 095 out.add(item); 096 097 return out; 098 } 099 100 /** 101 * Create an iterator that filters items from the given {@link Iterable}. 102 * 103 * @see Predicate#test(Object) 104 * 105 * @param <T> 106 * type of object being filtered 107 * @param iterable 108 * {@link Iterable} to filter 109 * @param filter 110 * the filter 111 * @return the list of accepted items 112 */ 113 public static <T> Iterator<T> filteredIterator(final Iterable<? extends T> iterable, final Predicate<T> filter) { 114 return filteredIterator(iterable.iterator(), filter); 115 } 116 117 /** 118 * Create an iterator that filters items from the given {@link Iterator}. 119 * 120 * @see Predicate#test(Object) 121 * 122 * @param <T> 123 * type of object being filtered 124 * @param iterator 125 * {@link Iterator} to filter 126 * @param filter 127 * the filter 128 * @return the list of accepted items 129 */ 130 public static <T> Iterator<T> filteredIterator(final Iterator<? extends T> iterator, final Predicate<T> filter) { 131 return new Iterator<T>() { 132 T next; 133 134 @Override 135 public boolean hasNext() { 136 if (next != null) 137 return true; 138 139 if (!iterator.hasNext()) 140 return false; 141 142 while (iterator.hasNext()) { 143 next = iterator.next(); 144 145 if (filter.test(next)) 146 return true; 147 } 148 149 return false; 150 } 151 152 @Override 153 public T next() { 154 if (next == null) 155 hasNext(); 156 157 final T ret = next; 158 next = null; 159 return ret; 160 } 161 162 @Override 163 public void remove() { 164 iterator.remove(); 165 } 166 }; 167 } 168 169 /** 170 * Create an iterator that filters items from the given array. 171 * 172 * @see Predicate#test(Object) 173 * 174 * @param <T> 175 * type of object being filtered 176 * @param array 177 * to filter 178 * @param filter 179 * the filter 180 * @return the list of accepted items 181 */ 182 public static <T> Iterator<T> filteredIterator(final T[] array, final Predicate<T> filter) { 183 return filteredIterator(new ArrayIterator<T>(array), filter); 184 } 185}