001 /* 002 * Copyright (C) 2008 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 package com.google.common.collect; 018 019 import com.google.common.annotations.Beta; 020 import com.google.common.annotations.GwtCompatible; 021 import com.google.common.annotations.GwtIncompatible; 022 import com.google.common.base.Function; 023 import com.google.common.base.Optional; 024 import com.google.common.base.Preconditions; 025 import com.google.common.base.Predicate; 026 027 import java.util.Comparator; 028 import java.util.Iterator; 029 import java.util.List; 030 import java.util.SortedSet; 031 032 import javax.annotation.Nullable; 033 034 /** 035 * {@code FluentIterable} provides a rich interface for manipulating {@code Iterable}s in a chained 036 * fashion. A {@code FluentIterable} can be created from an {@code Iterable}, or from a set of 037 * elements. The following types of methods are provided on {@code FluentIterable}: 038 * <ul> 039 * <li>chained methods which return a new {@code FluentIterable} based in some way on the contents 040 * of the current one (for example {@link #transform}) 041 * <li>conversion methods which copy the {@code FluentIterable}'s contents into a new collection or 042 * array (for example {@link #toImmutableList}) 043 * <li>element extraction methods which facilitate the retrieval of certain elements (for example 044 * {@link #last}) 045 * <li>query methods which answer questions about the {@code FluentIterable}'s contents (for example 046 * {@link #anyMatch}) 047 * </ul> 048 * 049 * <p>Here is an example that merges the lists returned by two separate database calls, transforms 050 * it by invoking {@code toString()} on each element, and returns the first 10 elements as an 051 * {@code ImmutableList}: <pre> {@code 052 * 053 * FluentIterable 054 * .from(database.getClientList()) 055 * .transform(Functions.toStringFunction()) 056 * .limit(10) 057 * .toImmutableList();}</pre> 058 * 059 * Anything which can be done using {@code FluentIterable} could be done in a different fashion 060 * (often with {@link Iterables}), however the use of {@code FluentIterable} makes many sets of 061 * operations significantly more concise. 062 * 063 * @author Marcin Mikosik 064 * @since 12.0 065 */ 066 @Beta 067 @GwtCompatible(emulated = true) 068 public abstract class FluentIterable<E> implements Iterable<E> { 069 // We store 'iterable' and use it instead of 'this' to allow Iterables to perform instanceof 070 // checks on the _original_ iterable when FluentIterable.from is used. 071 private final Iterable<E> iterable; 072 073 /** Constructor for use by subclasses. */ 074 protected FluentIterable() { 075 this.iterable = this; 076 } 077 078 FluentIterable(Iterable<E> iterable) { 079 this.iterable = Preconditions.checkNotNull(iterable); 080 } 081 082 /** 083 * Returns a fluent iterable that wraps {@code iterable}, or {@code iterable} itself if it 084 * is already a {@code FluentIterable}. 085 */ 086 public static <E> FluentIterable<E> from(final Iterable<E> iterable) { 087 return (iterable instanceof FluentIterable) ? (FluentIterable<E>) iterable 088 : new FluentIterable<E>(iterable) { 089 @Override 090 public Iterator<E> iterator() { 091 return iterable.iterator(); 092 } 093 }; 094 } 095 096 /** 097 * Construct a fluent iterable from another fluent iterable. This is obviously never necessary, 098 * but is intended to help call out cases where one migration from {@code Iterable} to 099 * {@code FluentIterable} has obviated the need to explicitly convert to a {@code FluentIterable}. 100 * 101 * @deprecated instances of {@code FluentIterable} don't need to be converted to 102 * {@code FluentIterable} 103 */ 104 @Deprecated 105 public static <E> FluentIterable<E> from(FluentIterable<E> iterable) { 106 return Preconditions.checkNotNull(iterable); 107 } 108 109 /** 110 * Returns a string representation of this fluent iterable, with the format 111 * {@code [e1, e2, ..., en]}. 112 */ 113 @Override 114 public String toString() { 115 return Iterables.toString(iterable); 116 } 117 118 /** 119 * Returns the number of elements in this fluent iterable. 120 */ 121 public final int size() { 122 return Iterables.size(iterable); 123 } 124 125 /** 126 * Returns {@code true} if this fluent iterable contains any object for which 127 * {@code equals(element)} is true. 128 */ 129 public final boolean contains(@Nullable Object element) { 130 return Iterables.contains(iterable, element); 131 } 132 133 /** 134 * Returns a fluent iterable whose {@code Iterator} cycles indefinitely over the elements of 135 * this fluent iterable. 136 * 137 * <p>That iterator supports {@code remove()} if {@code iterable.iterator()} does. After 138 * {@code remove()} is called, subsequent cycles omit the removed element, which is no longer in 139 * this fluent iterable. The iterator's {@code hasNext()} method returns {@code true} until 140 * this fluent iterable is empty. 141 * 142 * <p><b>Warning:</b> Typical uses of the resulting iterator may produce an infinite loop. You 143 * should use an explicit {@code break} or be certain that you will eventually remove all the 144 * elements. 145 */ 146 public final FluentIterable<E> cycle() { 147 return from(Iterables.cycle(iterable)); 148 } 149 150 /** 151 * Returns the elements from this fluent iterable that satisfy a predicate. The 152 * resulting fluent iterable's iterator does not support {@code remove()}. 153 */ 154 public final FluentIterable<E> filter(Predicate<? super E> predicate) { 155 return from(Iterables.filter(iterable, predicate)); 156 } 157 158 /** 159 * Returns the elements from this fluent iterable that are instances of class {@code type}. 160 * 161 * @param type the type of elements desired 162 */ 163 @GwtIncompatible("Class.isInstance") 164 public final <T> FluentIterable<T> filter(Class<T> type) { 165 return from(Iterables.filter(iterable, type)); 166 } 167 168 /** 169 * Returns {@code true} if any element in this fluent iterable satisfies the predicate. 170 */ 171 public final boolean anyMatch(Predicate<? super E> predicate) { 172 return Iterables.any(iterable, predicate); 173 } 174 175 /** 176 * Returns {@code true} if every element in this fluent iterable satisfies the predicate. 177 * If this fluent iterable is empty, {@code true} is returned. 178 */ 179 public final boolean allMatch(Predicate<? super E> predicate) { 180 return Iterables.all(iterable, predicate); 181 } 182 183 /** 184 * Returns an {@link Optional} containing the first element in this fluent iterable that 185 * satisfies the given predicate, if such an element exists. 186 * 187 * <p><b>Warning:</b> avoid using a {@code predicate} that matches {@code null}. If {@code null} 188 * is matched in this fluent iterable, a {@link NullPointerException} will be thrown. 189 */ 190 public final Optional<E> firstMatch(Predicate<? super E> predicate) { 191 return Iterables.tryFind(iterable, predicate); 192 } 193 194 /** 195 * Returns a fluent iterable that applies {@code function} to each element of this 196 * fluent iterable. 197 * 198 * <p>The returned fluent iterable's iterator supports {@code remove()} if this iterable's 199 * iterator does. After a successful {@code remove()} call, this fluent iterable no longer 200 * contains the corresponding element. 201 */ 202 public final <T> FluentIterable<T> transform(Function<? super E, T> function) { 203 return from(Iterables.transform(iterable, function)); 204 } 205 206 /** 207 * Returns an {@link Optional} containing the first element in this fluent iterable. 208 * If the iterable is empty, {@code Optional.absent()} is returned. 209 * 210 * @throws NullPointerException if the first element is null; if this is a possibility, use 211 * {@code iterator().next()} or {@link Iterables#getFirst} instead. 212 */ 213 public final Optional<E> first() { 214 Iterator<E> iterator = iterable.iterator(); 215 return iterator.hasNext() 216 ? Optional.of(iterator.next()) 217 : Optional.<E>absent(); 218 } 219 220 /** 221 * Returns an {@link Optional} containing the last element in this fluent iterable. 222 * If the iterable is empty, {@code Optional.absent()} is returned. 223 * 224 * @throws NullPointerException if the last element is null; if this is a possibility, use 225 * {@link Iterables#getLast} instead. 226 */ 227 public final Optional<E> last() { 228 // Iterables#getLast was inlined here so we don't have to throw/catch a NSEE 229 230 // TODO(kevinb): Support a concurrently modified collection? 231 if (iterable instanceof List) { 232 List<E> list = (List<E>) iterable; 233 if (list.isEmpty()) { 234 return Optional.absent(); 235 } 236 return Optional.of(list.get(list.size() - 1)); 237 } 238 Iterator<E> iterator = iterable.iterator(); 239 if (!iterator.hasNext()) { 240 return Optional.absent(); 241 } 242 243 /* 244 * TODO(kevinb): consider whether this "optimization" is worthwhile. Users 245 * with SortedSets tend to know they are SortedSets and probably would not 246 * call this method. 247 */ 248 if (iterable instanceof SortedSet) { 249 SortedSet<E> sortedSet = (SortedSet<E>) iterable; 250 return Optional.of(sortedSet.last()); 251 } 252 253 while (true) { 254 E current = iterator.next(); 255 if (!iterator.hasNext()) { 256 return Optional.of(current); 257 } 258 } 259 } 260 261 /** 262 * Returns a view of this fluent iterable that skips its first {@code numberToSkip} 263 * elements. If this fluent iterable contains fewer than {@code numberToSkip} elements, 264 * the returned fluent iterable skips all of its elements. 265 * 266 * <p>Modifications to this fluent iterable before a call to {@code iterator()} are 267 * reflected in the returned fluent iterable. That is, the its iterator skips the first 268 * {@code numberToSkip} elements that exist when the iterator is created, not when {@code skip()} 269 * is called. 270 * 271 * <p>The returned fluent iterable's iterator supports {@code remove()} if the 272 * {@code Iterator} of this fluent iterable supports it. Note that it is <i>not</i> 273 * possible to delete the last skipped element by immediately calling {@code remove()} on the 274 * returned fluent iterable's iterator, as the {@code Iterator} contract states that a call 275 * to {@code * remove()} before a call to {@code next()} will throw an 276 * {@link IllegalStateException}. 277 */ 278 public final FluentIterable<E> skip(int numberToSkip) { 279 return from(Iterables.skip(iterable, numberToSkip)); 280 } 281 282 /** 283 * Creates a fluent iterable with the first {@code size} elements of this 284 * fluent iterable. If this fluent iterable does not contain that many elements, 285 * the returned fluent iterable will have the same behavior as this fluent iterable. 286 * The returned fluent iterable's iterator supports {@code remove()} if this 287 * fluent iterable's iterator does. 288 * 289 * @param size the maximum number of elements in the returned fluent iterable 290 * @throws IllegalArgumentException if {@code size} is negative 291 */ 292 public final FluentIterable<E> limit(int size) { 293 return from(Iterables.limit(iterable, size)); 294 } 295 296 /** 297 * Determines whether this fluent iterable is empty. 298 */ 299 public final boolean isEmpty() { 300 return !iterable.iterator().hasNext(); 301 } 302 303 /** 304 * Returns an {@code ImmutableList} containing all of the elements from this 305 * fluent iterable in proper sequence. 306 */ 307 public final ImmutableList<E> toImmutableList() { 308 return ImmutableList.copyOf(iterable); 309 } 310 311 /** 312 * Returns an {@code ImmutableSet} containing all of the elements from this 313 * fluent iterable with duplicates removed. 314 */ 315 public final ImmutableSet<E> toImmutableSet() { 316 return ImmutableSet.copyOf(iterable); 317 } 318 319 /** 320 * Returns an {@code ImmutableSortedSet} containing all of the elements from this 321 * {@code FluentIterable} in the order specified by {@code comparator}, with duplicates 322 * (determined by {@code comaprator.compare(x, y) == 0}) removed. To produce an 323 * {@code ImmutableSortedSet} sorted by its natural ordering, use 324 * {@code toImmutableSortedSet(Ordering.natural())}. 325 * 326 * @param comparator the function by which to sort set elements 327 * @throws NullPointerException if any element is null 328 */ 329 public final ImmutableSortedSet<E> toImmutableSortedSet(Comparator<? super E> comparator) { 330 return ImmutableSortedSet.copyOf(comparator, iterable); 331 } 332 333 /** 334 * Returns an array containing all of the elements from this fluent iterable in iteration order. 335 * 336 * @param type the type of the elements 337 * @return a newly-allocated array into which all the elements of this fluent iterable have 338 * been copied 339 */ 340 @GwtIncompatible("Array.newArray(Class, int)") 341 public final E[] toArray(Class<E> type) { 342 return Iterables.toArray(iterable, type); 343 } 344 345 /** 346 * Returns the element at the specified position in this fluent iterable. 347 * 348 * @param position position of the element to return 349 * @return the element at the specified position in this fluent iterable 350 * @throws IndexOutOfBoundsException if {@code position} is negative or greater than or equal to 351 * the size of this fluent iterable 352 */ 353 public final E get(int position) { 354 return Iterables.get(iterable, position); 355 } 356 357 /** 358 * Function that transforms {@code Iterable<E>} into a fluent iterable. 359 */ 360 private static class FromIterableFunction<E> 361 implements Function<Iterable<E>, FluentIterable<E>> { 362 @Override 363 public FluentIterable<E> apply(Iterable<E> fromObject) { 364 return FluentIterable.from(fromObject); 365 } 366 } 367 }