1 /* 2 * Copyright (C) 2007 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.collect; 18 19 import com.google.common.annotations.GwtCompatible; 20 import com.google.common.annotations.GwtIncompatible; 21 import com.google.common.base.Function; 22 import com.google.common.base.Objects; 23 import com.google.common.base.Preconditions; 24 import com.google.common.base.Predicate; 25 26 import java.util.Arrays; 27 import java.util.Collection; 28 import java.util.Collections; 29 import java.util.HashSet; 30 import java.util.Iterator; 31 import java.util.List; 32 import java.util.ListIterator; 33 import java.util.NoSuchElementException; 34 import java.util.RandomAccess; 35 import java.util.Set; 36 import java.util.SortedSet; 37 38 import javax.annotation.Nullable; 39 40 import static com.google.common.base.Preconditions.checkArgument; 41 import static com.google.common.base.Preconditions.checkNotNull; 42 43 /** 44 * This class contains static utility methods that operate on or return objects 45 * of type {@code Iterable}. Except as noted, each method has a corresponding 46 * {@link Iterator}-based method in the {@link Iterators} class. 47 * 48 * @author Kevin Bourrillion 49 * @author Jared Levy 50 * @since 2010.01.04 <b>stable</b> (imported from Google Collections Library) 51 */ 52 @GwtCompatible 53 public final class Iterables { 54 private Iterables() {} 55 56 /** Returns an unmodifiable view of {@code iterable}. */ 57 public static <T> Iterable<T> unmodifiableIterable(final Iterable<T> iterable) 58 { 59 checkNotNull(iterable); 60 return new Iterable<T>() { 61 public Iterator<T> iterator() { 62 return Iterators.unmodifiableIterator(iterable.iterator()); 63 } 64 @Override public String toString() { 65 return iterable.toString(); 66 } 67 // no equals and hashCode; it would break the contract! 68 }; 69 } 70 71 /** 72 * Returns the number of elements in {@code iterable}. 73 */ 74 public static int size(Iterable<?> iterable) { 75 return (iterable instanceof Collection) 76 ? ((Collection<?>) iterable).size() 77 : Iterators.size(iterable.iterator()); 78 } 79 80 /** 81 * Returns {@code true} if {@code iterable} contains {@code element}; that is, 82 * any object for while {@code equals(element)} is true. 83 */ 84 public static boolean contains(Iterable<?> iterable, @Nullable Object element) 85 { 86 if (iterable instanceof Collection) { 87 Collection<?> collection = (Collection<?>) iterable; 88 try { 89 return collection.contains(element); 90 } catch (NullPointerException e) { 91 return false; 92 } catch (ClassCastException e) { 93 return false; 94 } 95 } 96 return Iterators.contains(iterable.iterator(), element); 97 } 98 99 /** 100 * Removes, from an iterable, every element that belongs to the provided 101 * collection. 102 * 103 * <p>This method calls {@link Collection#removeAll} if {@code iterable} is a 104 * collection, and {@link Iterators#removeAll} otherwise. 105 * 106 * @param removeFrom the iterable to (potentially) remove elements from 107 * @param elementsToRemove the elements to remove 108 * @return {@code true} if any elements are removed from {@code iterable} 109 */ 110 public static boolean removeAll( 111 Iterable<?> removeFrom, Collection<?> elementsToRemove) { 112 return (removeFrom instanceof Collection) 113 ? ((Collection<?>) removeFrom).removeAll(checkNotNull(elementsToRemove)) 114 : Iterators.removeAll(removeFrom.iterator(), elementsToRemove); 115 } 116 117 /** 118 * Removes, from an iterable, every element that does not belong to the 119 * provided collection. 120 * 121 * <p>This method calls {@link Collection#retainAll} if {@code iterable} is a 122 * collection, and {@link Iterators#retainAll} otherwise. 123 * 124 * @param removeFrom the iterable to (potentially) remove elements from 125 * @param elementsToRetain the elements to retain 126 * @return {@code true} if any elements are removed from {@code iterable} 127 */ 128 public static boolean retainAll( 129 Iterable<?> removeFrom, Collection<?> elementsToRetain) { 130 return (removeFrom instanceof Collection) 131 ? ((Collection<?>) removeFrom).retainAll(checkNotNull(elementsToRetain)) 132 : Iterators.retainAll(removeFrom.iterator(), elementsToRetain); 133 } 134 135 /** 136 * Removes, from an iterable, every element that satisfies the provided 137 * predicate. 138 * 139 * @param removeFrom the iterable to (potentially) remove elements from 140 * @param predicate a predicate that determines whether an element should 141 * be removed 142 * @return {@code true} if any elements were removed from the iterable 143 * 144 * @throws UnsupportedOperationException if the iterable does not support 145 * {@code remove()}. 146 * @since 2010.01.04 <b>tentative</b> 147 */ 148 public static <T> boolean removeIf( 149 Iterable<T> removeFrom, Predicate<? super T> predicate) { 150 if (removeFrom instanceof RandomAccess && removeFrom instanceof List) { 151 return removeIfFromRandomAccessList( 152 (List<T>) removeFrom, checkNotNull(predicate)); 153 } 154 return Iterators.removeIf(removeFrom.iterator(), predicate); 155 } 156 157 private static <T> boolean removeIfFromRandomAccessList( 158 List<T> list, Predicate<? super T> predicate) { 159 int from = 0; 160 int to = 0; 161 162 for (; from < list.size(); from++) { 163 T element = list.get(from); 164 if (!predicate.apply(element)) { 165 if (from > to) { 166 list.set(to, element); 167 } 168 to++; 169 } 170 } 171 172 // Clear the tail of any remaining items 173 // Note: hand-written GWT-compatible version of 174 // list.subList(to, list.size()).clear(); 175 ListIterator<T> iter = list.listIterator(list.size()); 176 for (int idx = from - to; idx > 0; idx--) { 177 iter.previous(); 178 iter.remove(); 179 } 180 181 return from != to; 182 } 183 184 /** 185 * Determines whether two iterables contain equal elements in the same order. 186 * More specifically, this method returns {@code true} if {@code iterable1} 187 * and {@code iterable2} contain the same number of elements and every element 188 * of {@code iterable1} is equal to the corresponding element of 189 * {@code iterable2}. 190 */ 191 public static boolean elementsEqual( 192 Iterable<?> iterable1, Iterable<?> iterable2) { 193 return Iterators.elementsEqual(iterable1.iterator(), iterable2.iterator()); 194 } 195 196 /** 197 * Returns a string representation of {@code iterable}, with the format 198 * {@code [e1, e2, ..., en]}. 199 */ 200 public static String toString(Iterable<?> iterable) { 201 return Iterators.toString(iterable.iterator()); 202 } 203 204 /** 205 * Returns the single element contained in {@code iterable}. 206 * 207 * @throws NoSuchElementException if the iterable is empty 208 * @throws IllegalArgumentException if the iterable contains multiple 209 * elements 210 */ 211 public static <T> T getOnlyElement(Iterable<T> iterable) { 212 return Iterators.getOnlyElement(iterable.iterator()); 213 } 214 215 /** 216 * Returns the single element contained in {@code iterable}, or {@code 217 * defaultValue} if the iterable is empty. 218 * 219 * @throws IllegalArgumentException if the iterator contains multiple 220 * elements 221 */ 222 public static <T> T getOnlyElement( 223 Iterable<T> iterable, @Nullable T defaultValue) { 224 return Iterators.getOnlyElement(iterable.iterator(), defaultValue); 225 } 226 227 /** 228 * Copies an iterable's elements into an array. 229 * 230 * @param iterable the iterable to copy 231 * @param type the type of the elements 232 * @return a newly-allocated array into which all the elements of the iterable 233 * have been copied 234 */ 235 @GwtIncompatible("Array.newInstance(Class, int)") 236 public static <T> T[] toArray(Iterable<? extends T> iterable, Class<T> type) { 237 @SuppressWarnings("unchecked") // bugs.sun.com/view_bug.do?bug_id=6558557 238 Collection<? extends T> collection = (iterable instanceof Collection) 239 ? (Collection<? extends T>) iterable 240 : Lists.newArrayList(iterable); 241 T[] array = ObjectArrays.newArray(type, collection.size()); 242 return collection.toArray(array); 243 } 244 245 /** 246 * Adds all elements in {@code iterable} to {@code collection}. 247 * 248 * @return {@code true} if {@code collection} was modified as a result of this 249 * operation. 250 */ 251 public static <T> boolean addAll( 252 Collection<T> addTo, Iterable<? extends T> elementsToAdd) { 253 if (elementsToAdd instanceof Collection) { 254 @SuppressWarnings("unchecked") 255 Collection<? extends T> c = (Collection<? extends T>) elementsToAdd; 256 return addTo.addAll(c); 257 } 258 return Iterators.addAll(addTo, elementsToAdd.iterator()); 259 } 260 261 /** 262 * Returns the number of elements in the specified iterable that equal the 263 * specified object. 264 * 265 * @see Collections#frequency 266 */ 267 public static int frequency(Iterable<?> iterable, @Nullable Object element) { 268 if ((iterable instanceof Multiset)) { 269 return ((Multiset<?>) iterable).count(element); 270 } 271 if ((iterable instanceof Set)) { 272 return ((Set<?>) iterable).contains(element) ? 1 : 0; 273 } 274 return Iterators.frequency(iterable.iterator(), element); 275 } 276 277 /** 278 * Returns an iterable whose iterators cycle indefinitely over the elements of 279 * {@code iterable}. 280 * 281 * <p>That iterator supports {@code remove()} if {@code iterable.iterator()} 282 * does. After {@code remove()} is called, subsequent cycles omit the removed 283 * element, which is no longer in {@code iterable}. The iterator's 284 * {@code hasNext()} method returns {@code true} until {@code iterable} is 285 * empty. 286 * 287 * <p><b>Warning:</b> Typical uses of the resulting iterator may produce an 288 * infinite loop. You should use an explicit {@code break} or be certain that 289 * you will eventually remove all the elements. 290 * 291 * <p>To cycle over the iterable {@code n} times, use the following: 292 * {@code Iterables.concat(Collections.nCopies(n, iterable))} 293 */ 294 public static <T> Iterable<T> cycle(final Iterable<T> iterable) { 295 checkNotNull(iterable); 296 return new Iterable<T>() { 297 public Iterator<T> iterator() { 298 return Iterators.cycle(iterable); 299 } 300 @Override public String toString() { 301 return iterable.toString() + " (cycled)"; 302 } 303 }; 304 } 305 306 /** 307 * Returns an iterable whose iterators cycle indefinitely over the provided 308 * elements. 309 * 310 * <p>After {@code remove} is invoked on a generated iterator, the removed 311 * element will no longer appear in either that iterator or any other iterator 312 * created from the same source iterable. That is, this method behaves exactly 313 * as {@code Iterables.cycle(Lists.newArrayList(elements))}. The iterator's 314 * {@code hasNext} method returns {@code true} until all of the original 315 * elements have been removed. 316 * 317 * <p><b>Warning:</b> Typical uses of the resulting iterator may produce an 318 * infinite loop. You should use an explicit {@code break} or be certain that 319 * you will eventually remove all the elements. 320 * 321 * <p>To cycle over the elements {@code n} times, use the following: 322 * {@code Iterables.concat(Collections.nCopies(n, Arrays.asList(elements)))} 323 */ 324 public static <T> Iterable<T> cycle(T... elements) { 325 return cycle(Lists.newArrayList(elements)); 326 } 327 328 /** 329 * Combines two iterables into a single iterable. The returned iterable has an 330 * iterator that traverses the elements in {@code a}, followed by the elements 331 * in {@code b}. The source iterators are not polled until necessary. 332 * 333 * <p>The returned iterable's iterator supports {@code remove()} when the 334 * corresponding input iterator supports it. 335 */ 336 @SuppressWarnings("unchecked") 337 public static <T> Iterable<T> concat( 338 Iterable<? extends T> a, Iterable<? extends T> b) { 339 checkNotNull(a); 340 checkNotNull(b); 341 return concat(Arrays.asList(a, b)); 342 } 343 344 /** 345 * Combines three iterables into a single iterable. The returned iterable has 346 * an iterator that traverses the elements in {@code a}, followed by the 347 * elements in {@code b}, followed by the elements in {@code c}. The source 348 * iterators are not polled until necessary. 349 * 350 * <p>The returned iterable's iterator supports {@code remove()} when the 351 * corresponding input iterator supports it. 352 */ 353 @SuppressWarnings("unchecked") 354 public static <T> Iterable<T> concat(Iterable<? extends T> a, 355 Iterable<? extends T> b, Iterable<? extends T> c) { 356 checkNotNull(a); 357 checkNotNull(b); 358 checkNotNull(c); 359 return concat(Arrays.asList(a, b, c)); 360 } 361 362 /** 363 * Combines four iterables into a single iterable. The returned iterable has 364 * an iterator that traverses the elements in {@code a}, followed by the 365 * elements in {@code b}, followed by the elements in {@code c}, followed by 366 * the elements in {@code d}. The source iterators are not polled until 367 * necessary. 368 * 369 * <p>The returned iterable's iterator supports {@code remove()} when the 370 * corresponding input iterator supports it. 371 */ 372 @SuppressWarnings("unchecked") 373 public static <T> Iterable<T> concat(Iterable<? extends T> a, 374 Iterable<? extends T> b, Iterable<? extends T> c, 375 Iterable<? extends T> d) { 376 checkNotNull(a); 377 checkNotNull(b); 378 checkNotNull(c); 379 checkNotNull(d); 380 return concat(Arrays.asList(a, b, c, d)); 381 } 382 383 /** 384 * Combines multiple iterables into a single iterable. The returned iterable 385 * has an iterator that traverses the elements of each iterable in 386 * {@code inputs}. The input iterators are not polled until necessary. 387 * 388 * <p>The returned iterable's iterator supports {@code remove()} when the 389 * corresponding input iterator supports it. 390 * 391 * @throws NullPointerException if any of the provided iterables is null 392 */ 393 public static <T> Iterable<T> concat(Iterable<? extends T>... inputs) { 394 return concat(ImmutableList.of(inputs)); 395 } 396 397 /** 398 * Combines multiple iterables into a single iterable. The returned iterable 399 * has an iterator that traverses the elements of each iterable in 400 * {@code inputs}. The input iterators are not polled until necessary. 401 * 402 * <p>The returned iterable's iterator supports {@code remove()} when the 403 * corresponding input iterator supports it. The methods of the returned 404 * iterable may throw {@code NullPointerException} if any of the input 405 * iterators are null. 406 */ 407 public static <T> Iterable<T> concat( 408 Iterable<? extends Iterable<? extends T>> inputs) { 409 /* 410 * Hint: if you let A represent Iterable<? extends T> and B represent 411 * Iterator<? extends T>, then this Function would look simply like: 412 * 413 * Function<A, B> function = new Function<A, B> { 414 * public B apply(A from) { 415 * return from.iterator(); 416 * } 417 * } 418 * 419 * TODO: there may be a better way to do this. 420 */ 421 422 Function<Iterable<? extends T>, Iterator<? extends T>> function 423 = new Function<Iterable<? extends T>, Iterator<? extends T>>() { 424 public Iterator<? extends T> apply(Iterable<? extends T> from) { 425 return from.iterator(); 426 } 427 }; 428 final Iterable<Iterator<? extends T>> iterators 429 = transform(inputs, function); 430 return new IterableWithToString<T>() { 431 public Iterator<T> iterator() { 432 return Iterators.concat(iterators.iterator()); 433 } 434 }; 435 } 436 437 /** 438 * Divides an iterable into unmodifiable sublists of the given size (the final 439 * iterable may be smaller). For example, partitioning an iterable containing 440 * {@code [a, b, c, d, e]} with a partition size of 3 yields {@code 441 * [[a, b, c], [d, e]]} -- an outer iterable containing two inner lists of 442 * three and two elements, all in the original order. 443 * 444 * <p>Iterators returned by the returned iterable do not support the {@link 445 * Iterator#remove()} method. The returned lists implement {@link 446 * RandomAccess}, whether or not the input list does. 447 * 448 * <p><b>Note:</b> if {@code iterable} is a {@link List}, use {@link 449 * Lists#partition(List, int)} instead. 450 * 451 * @param iterable the iterable to return a partitioned view of 452 * @param size the desired size of each partition (the last may be smaller) 453 * @return an iterable of unmodifiable lists containing the elements of {@code 454 * iterable} divided into partitions 455 * @throws IllegalArgumentException if {@code size} is nonpositive 456 */ 457 public static <T> Iterable<List<T>> partition( 458 final Iterable<T> iterable, final int size) { 459 checkNotNull(iterable); 460 checkArgument(size > 0); 461 return new IterableWithToString<List<T>>() { 462 public Iterator<List<T>> iterator() { 463 return Iterators.partition(iterable.iterator(), size); 464 } 465 }; 466 } 467 468 /** 469 * Divides an iterable into unmodifiable sublists of the given size, padding 470 * the final iterable with null values if necessary. For example, partitioning 471 * an iterable containing {@code [a, b, c, d, e]} with a partition size of 3 472 * yields {@code [[a, b, c], [d, e, null]]} -- an outer iterable containing 473 * two inner lists of three elements each, all in the original order. 474 * 475 * <p>Iterators returned by the returned iterable do not support the {@link 476 * Iterator#remove()} method. 477 * 478 * @param iterable the iterable to return a partitioned view of 479 * @param size the desired size of each partition 480 * @return an iterable of unmodifiable lists containing the elements of {@code 481 * iterable} divided into partitions (the final iterable may have 482 * trailing null elements) 483 * @throws IllegalArgumentException if {@code size} is nonpositive 484 */ 485 public static <T> Iterable<List<T>> paddedPartition( 486 final Iterable<T> iterable, final int size) { 487 checkNotNull(iterable); 488 checkArgument(size > 0); 489 return new IterableWithToString<List<T>>() { 490 public Iterator<List<T>> iterator() { 491 return Iterators.paddedPartition(iterable.iterator(), size); 492 } 493 }; 494 } 495 496 /** 497 * Returns the elements of {@code unfiltered} that satisfy a predicate. The 498 * resulting iterable's iterator does not support {@code remove()}. 499 */ 500 public static <T> Iterable<T> filter( 501 final Iterable<T> unfiltered, final Predicate<? super T> predicate) { 502 checkNotNull(unfiltered); 503 checkNotNull(predicate); 504 return new IterableWithToString<T>() { 505 public Iterator<T> iterator() { 506 return Iterators.filter(unfiltered.iterator(), predicate); 507 } 508 }; 509 } 510 511 /** 512 * Returns all instances of class {@code type} in {@code unfiltered}. The 513 * returned iterable has elements whose class is {@code type} or a subclass of 514 * {@code type}. The returned iterable's iterator does not support 515 * {@code remove()}. 516 * 517 * @param unfiltered an iterable containing objects of any type 518 * @param type the type of elements desired 519 * @return an unmodifiable iterable containing all elements of the original 520 * iterable that were of the requested type 521 */ 522 @GwtIncompatible("Class.isInstance") 523 public static <T> Iterable<T> filter( 524 final Iterable<?> unfiltered, final Class<T> type) { 525 checkNotNull(unfiltered); 526 checkNotNull(type); 527 return new IterableWithToString<T>() { 528 public Iterator<T> iterator() { 529 return Iterators.filter(unfiltered.iterator(), type); 530 } 531 }; 532 } 533 534 /** 535 * Returns {@code true} if one or more elements in {@code iterable} satisfy 536 * the predicate. 537 */ 538 public static <T> boolean any( 539 Iterable<T> iterable, Predicate<? super T> predicate) { 540 return Iterators.any(iterable.iterator(), predicate); 541 } 542 543 /** 544 * Returns {@code true} if every element in {@code iterable} satisfies the 545 * predicate. If {@code iterable} is empty, {@code true} is returned. 546 */ 547 public static <T> boolean all( 548 Iterable<T> iterable, Predicate<? super T> predicate) { 549 return Iterators.all(iterable.iterator(), predicate); 550 } 551 552 /** 553 * Returns the first element in {@code iterable} that satisfies the given 554 * predicate. 555 * 556 * @throws NoSuchElementException if no element in {@code iterable} matches 557 * the given predicate 558 */ 559 public static <T> T find(Iterable<T> iterable, 560 Predicate<? super T> predicate) { 561 return Iterators.find(iterable.iterator(), predicate); 562 } 563 564 /** 565 * Returns the index in {@code iterable} of the first element that satisfies 566 * the provided {@code predicate}, or {@code -1} if the Iterable has no such 567 * elements. 568 * 569 * <p>More formally, returns the lowest index {@code i} such that 570 * {@code predicate.apply(Iterables.get(iterable, i))} is {@code true} or 571 * {@code -1} if there is no such index. 572 * 573 * @since 2010.01.04 <b>tentative</b> 574 */ 575 public static <T> int indexOf( 576 Iterable<T> iterable, Predicate<? super T> predicate) { 577 return Iterators.indexOf(iterable.iterator(), predicate); 578 } 579 580 /** 581 * Returns an iterable that applies {@code function} to each element of {@code 582 * fromIterable}. 583 * 584 * <p>The returned iterable's iterator supports {@code remove()} if the 585 * provided iterator does. After a successful {@code remove()} call, 586 * {@code fromIterable} no longer contains the corresponding element. 587 */ 588 public static <F, T> Iterable<T> transform(final Iterable<F> fromIterable, 589 final Function<? super F, ? extends T> function) { 590 checkNotNull(fromIterable); 591 checkNotNull(function); 592 return new IterableWithToString<T>() { 593 public Iterator<T> iterator() { 594 return Iterators.transform(fromIterable.iterator(), function); 595 } 596 }; 597 } 598 599 /** 600 * Returns the element at the specified position in an iterable. 601 * 602 * @param position position of the element to return 603 * @return the element at the specified position in {@code iterable} 604 * @throws IndexOutOfBoundsException if {@code position} is negative or 605 * greater than or equal to the size of {@code iterable} 606 */ 607 public static <T> T get(Iterable<T> iterable, int position) { 608 checkNotNull(iterable); 609 if (iterable instanceof List) { 610 return ((List<T>) iterable).get(position); 611 } 612 613 if (iterable instanceof Collection) { 614 // Can check both ends 615 Collection<T> collection = (Collection<T>) iterable; 616 Preconditions.checkElementIndex(position, collection.size()); 617 } else { 618 // Can only check the lower end 619 if (position < 0) { 620 throw new IndexOutOfBoundsException( 621 "position cannot be negative: " + position); 622 } 623 } 624 return Iterators.get(iterable.iterator(), position); 625 } 626 627 /** 628 * Returns the last element of {@code iterable}. 629 * 630 * @return the last element of {@code iterable} 631 * @throws NoSuchElementException if the iterable has no elements 632 */ 633 public static <T> T getLast(Iterable<T> iterable) { 634 if (iterable instanceof List) { 635 List<T> list = (List<T>) iterable; 636 // TODO: Support a concurrent list whose size changes while this method 637 // is running. 638 if (list.isEmpty()) { 639 throw new NoSuchElementException(); 640 } 641 return list.get(list.size() - 1); 642 } 643 644 if (iterable instanceof SortedSet) { 645 SortedSet<T> sortedSet = (SortedSet<T>) iterable; 646 return sortedSet.last(); 647 } 648 649 return Iterators.getLast(iterable.iterator()); 650 } 651 652 /** 653 * Returns a view of the supplied iterable that wraps each generated 654 * {@link Iterator} through {@link Iterators#consumingIterator(Iterator)}. 655 * 656 * @param iterable the iterable to wrap 657 * @return a view of the supplied iterable that wraps each generated iterator 658 * through {@link Iterators#consumingIterator(Iterator)} 659 * 660 * @see Iterators#consumingIterator(Iterator) 661 * @since 2010.01.04 <b>tentative</b> 662 */ 663 public static <T> Iterable<T> consumingIterable(final Iterable<T> iterable) { 664 checkNotNull(iterable); 665 return new Iterable<T>() { 666 public Iterator<T> iterator() { 667 return Iterators.consumingIterator(iterable.iterator()); 668 } 669 }; 670 } 671 672 // Methods only in Iterables, not in Iterators 673 674 /** 675 * Adapts a list to an iterable with reversed iteration order. It is 676 * especially useful in foreach-style loops: <pre class="code"> {@code 677 * 678 * List<String> mylist = ... 679 * for (String str : Iterables.reverse(mylist)) { 680 * ... 681 * }}</pre> 682 * 683 * There is no corresponding method in {@link Iterators}, since {@link 684 * Iterable#iterator} can simply be invoked on the result of calling this 685 * method. 686 * 687 * @return an iterable with the same elements as the list, in reverse 688 */ 689 public static <T> Iterable<T> reverse(final List<T> list) { 690 checkNotNull(list); 691 return new IterableWithToString<T>() { 692 public Iterator<T> iterator() { 693 final ListIterator<T> listIter = list.listIterator(list.size()); 694 return new Iterator<T>() { 695 public boolean hasNext() { 696 return listIter.hasPrevious(); 697 } 698 public T next() { 699 return listIter.previous(); 700 } 701 public void remove() { 702 listIter.remove(); 703 } 704 }; 705 } 706 }; 707 } 708 709 /** 710 * Determines if the given iterable contains no elements. 711 * 712 * <p>There is no precise {@link Iterator} equivalent to this method, since 713 * one can only ask an iterator whether it has any elements <i>remaining</i> 714 * (which one does using {@link Iterator#hasNext}). 715 * 716 * @return {@code true} if the iterable contains no elements 717 */ 718 public static <T> boolean isEmpty(Iterable<T> iterable) { 719 return !iterable.iterator().hasNext(); 720 } 721 722 // Non-public 723 724 /** 725 * Removes the specified element from the specified iterable. 726 * 727 * <p>This method iterates over the iterable, checking each element returned 728 * by the iterator in turn to see if it equals the object {@code o}. If they 729 * are equal, it is removed from the iterable with the iterator's 730 * {@code remove} method. At most one element is removed, even if the iterable 731 * contains multiple members that equal {@code o}. 732 * 733 * <p><b>Warning</b>: Do not use this method for a collection, such as a 734 * {@link HashSet}, that has a fast {@code remove} method. 735 * 736 * @param iterable the iterable from which to remove 737 * @param o an element to remove from the collection 738 * @return {@code true} if the iterable changed as a result 739 * @throws UnsupportedOperationException if the iterator does not support the 740 * {@code remove} method and the iterable contains the object 741 */ 742 static boolean remove(Iterable<?> iterable, @Nullable Object o) { 743 Iterator<?> i = iterable.iterator(); 744 while (i.hasNext()) { 745 if (Objects.equal(i.next(), o)) { 746 i.remove(); 747 return true; 748 } 749 } 750 return false; 751 } 752 753 abstract static class IterableWithToString<E> implements Iterable<E> { 754 @Override public String toString() { 755 return Iterables.toString(this); 756 } 757 } 758 } 759