001 /* 002 * Copyright (C) 2007 Google Inc. 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 static com.google.common.base.Preconditions.checkArgument; 020 import static com.google.common.base.Preconditions.checkNotNull; 021 022 import com.google.common.annotations.Beta; 023 import com.google.common.annotations.GwtCompatible; 024 import com.google.common.annotations.GwtIncompatible; 025 import com.google.common.base.Function; 026 import com.google.common.base.Objects; 027 import com.google.common.base.Preconditions; 028 import com.google.common.base.Predicate; 029 030 import java.util.Arrays; 031 import java.util.Collection; 032 import java.util.Collections; 033 import java.util.HashSet; 034 import java.util.Iterator; 035 import java.util.List; 036 import java.util.ListIterator; 037 import java.util.NoSuchElementException; 038 import java.util.RandomAccess; 039 import java.util.Set; 040 import java.util.SortedSet; 041 042 import javax.annotation.Nullable; 043 044 /** 045 * This class contains static utility methods that operate on or return objects 046 * of type {@code Iterable}. Except as noted, each method has a corresponding 047 * {@link Iterator}-based method in the {@link Iterators} class. 048 * 049 * <p><i>Performance notes:</i> Unless otherwise noted, all of the iterables 050 * produced in this class are <i>lazy</i>, which means that their iterators 051 * only advance the backing iteration when absolutely necessary. 052 * 053 * @author Kevin Bourrillion 054 * @author Jared Levy 055 * @since 2 (imported from Google Collections Library) 056 */ 057 @GwtCompatible(emulated = true) 058 public final class Iterables { 059 private Iterables() {} 060 061 /** Returns an unmodifiable view of {@code iterable}. */ 062 public static <T> Iterable<T> unmodifiableIterable(final Iterable<T> iterable) 063 { 064 checkNotNull(iterable); 065 return new Iterable<T>() { 066 public Iterator<T> iterator() { 067 return Iterators.unmodifiableIterator(iterable.iterator()); 068 } 069 @Override public String toString() { 070 return iterable.toString(); 071 } 072 // no equals and hashCode; it would break the contract! 073 }; 074 } 075 076 /** 077 * Returns the number of elements in {@code iterable}. 078 */ 079 public static int size(Iterable<?> iterable) { 080 return (iterable instanceof Collection) 081 ? ((Collection<?>) iterable).size() 082 : Iterators.size(iterable.iterator()); 083 } 084 085 /** 086 * Returns {@code true} if {@code iterable} contains {@code element}; that is, 087 * any object for which {@code equals(element)} is true. 088 */ 089 public static boolean contains(Iterable<?> iterable, @Nullable Object element) 090 { 091 if (iterable instanceof Collection) { 092 Collection<?> collection = (Collection<?>) iterable; 093 try { 094 return collection.contains(element); 095 } catch (NullPointerException e) { 096 return false; 097 } catch (ClassCastException e) { 098 return false; 099 } 100 } 101 return Iterators.contains(iterable.iterator(), element); 102 } 103 104 /** 105 * Removes, from an iterable, every element that belongs to the provided 106 * collection. 107 * 108 * <p>This method calls {@link Collection#removeAll} if {@code iterable} is a 109 * collection, and {@link Iterators#removeAll} otherwise. 110 * 111 * @param removeFrom the iterable to (potentially) remove elements from 112 * @param elementsToRemove the elements to remove 113 * @return {@code true} if any elements are removed from {@code iterable} 114 */ 115 public static boolean removeAll( 116 Iterable<?> removeFrom, Collection<?> elementsToRemove) { 117 return (removeFrom instanceof Collection) 118 ? ((Collection<?>) removeFrom).removeAll(checkNotNull(elementsToRemove)) 119 : Iterators.removeAll(removeFrom.iterator(), elementsToRemove); 120 } 121 122 /** 123 * Removes, from an iterable, every element that does not belong to the 124 * provided collection. 125 * 126 * <p>This method calls {@link Collection#retainAll} if {@code iterable} is a 127 * collection, and {@link Iterators#retainAll} otherwise. 128 * 129 * @param removeFrom the iterable to (potentially) remove elements from 130 * @param elementsToRetain the elements to retain 131 * @return {@code true} if any elements are removed from {@code iterable} 132 */ 133 public static boolean retainAll( 134 Iterable<?> removeFrom, Collection<?> elementsToRetain) { 135 return (removeFrom instanceof Collection) 136 ? ((Collection<?>) removeFrom).retainAll(checkNotNull(elementsToRetain)) 137 : Iterators.retainAll(removeFrom.iterator(), elementsToRetain); 138 } 139 140 /** 141 * Removes, from an iterable, every element that satisfies the provided 142 * predicate. 143 * 144 * @param removeFrom the iterable to (potentially) remove elements from 145 * @param predicate a predicate that determines whether an element should 146 * be removed 147 * @return {@code true} if any elements were removed from the iterable 148 * 149 * @throws UnsupportedOperationException if the iterable does not support 150 * {@code remove()}. 151 * @since 2 152 */ 153 public static <T> boolean removeIf( 154 Iterable<T> removeFrom, Predicate<? super T> predicate) { 155 if (removeFrom instanceof RandomAccess && removeFrom instanceof List) { 156 return removeIfFromRandomAccessList( 157 (List<T>) removeFrom, checkNotNull(predicate)); 158 } 159 return Iterators.removeIf(removeFrom.iterator(), predicate); 160 } 161 162 private static <T> boolean removeIfFromRandomAccessList( 163 List<T> list, Predicate<? super T> predicate) { 164 int from = 0; 165 int to = 0; 166 167 for (; from < list.size(); from++) { 168 T element = list.get(from); 169 if (!predicate.apply(element)) { 170 if (from > to) { 171 list.set(to, element); 172 } 173 to++; 174 } 175 } 176 177 // Clear the tail of any remaining items 178 list.subList(to, list.size()).clear(); 179 return from != to; 180 } 181 182 /** 183 * Determines whether two iterables contain equal elements in the same order. 184 * More specifically, this method returns {@code true} if {@code iterable1} 185 * and {@code iterable2} contain the same number of elements and every element 186 * of {@code iterable1} is equal to the corresponding element of 187 * {@code iterable2}. 188 */ 189 public static boolean elementsEqual( 190 Iterable<?> iterable1, Iterable<?> iterable2) { 191 return Iterators.elementsEqual(iterable1.iterator(), iterable2.iterator()); 192 } 193 194 /** 195 * Returns a string representation of {@code iterable}, with the format 196 * {@code [e1, e2, ..., en]}. 197 */ 198 public static String toString(Iterable<?> iterable) { 199 return Iterators.toString(iterable.iterator()); 200 } 201 202 /** 203 * Returns the single element contained in {@code iterable}. 204 * 205 * @throws NoSuchElementException if the iterable is empty 206 * @throws IllegalArgumentException if the iterable contains multiple 207 * elements 208 */ 209 public static <T> T getOnlyElement(Iterable<T> iterable) { 210 return Iterators.getOnlyElement(iterable.iterator()); 211 } 212 213 /** 214 * Returns the single element contained in {@code iterable}, or {@code 215 * defaultValue} if the iterable is empty. 216 * 217 * @throws IllegalArgumentException if the iterator contains multiple 218 * elements 219 */ 220 public static <T> T getOnlyElement( 221 Iterable<T> iterable, @Nullable T defaultValue) { 222 return Iterators.getOnlyElement(iterable.iterator(), defaultValue); 223 } 224 225 /** 226 * Copies an iterable's elements into an array. 227 * 228 * @param iterable the iterable to copy 229 * @param type the type of the elements 230 * @return a newly-allocated array into which all the elements of the iterable 231 * have been copied 232 */ 233 public static <T> T[] toArray(Iterable<? extends T> iterable, Class<T> type) { 234 Collection<? extends T> collection = Collections2.toCollection(iterable); 235 T[] array = ObjectArrays.newArray(type, collection.size()); 236 return collection.toArray(array); 237 } 238 239 /** 240 * Adds all elements in {@code iterable} to {@code collection}. 241 * 242 * @return {@code true} if {@code collection} was modified as a result of this 243 * operation. 244 */ 245 public static <T> boolean addAll( 246 Collection<T> addTo, Iterable<? extends T> elementsToAdd) { 247 if (elementsToAdd instanceof Collection) { 248 @SuppressWarnings("unchecked") 249 Collection<? extends T> c = (Collection<? extends T>) elementsToAdd; 250 return addTo.addAll(c); 251 } 252 return Iterators.addAll(addTo, elementsToAdd.iterator()); 253 } 254 255 /** 256 * Returns the number of elements in the specified iterable that equal the 257 * specified object. 258 * 259 * @see Collections#frequency 260 */ 261 public static int frequency(Iterable<?> iterable, @Nullable Object element) { 262 if ((iterable instanceof Multiset)) { 263 return ((Multiset<?>) iterable).count(element); 264 } 265 if ((iterable instanceof Set)) { 266 return ((Set<?>) iterable).contains(element) ? 1 : 0; 267 } 268 return Iterators.frequency(iterable.iterator(), element); 269 } 270 271 /** 272 * Returns an iterable whose iterators cycle indefinitely over the elements of 273 * {@code iterable}. 274 * 275 * <p>That iterator supports {@code remove()} if {@code iterable.iterator()} 276 * does. After {@code remove()} is called, subsequent cycles omit the removed 277 * element, which is no longer in {@code iterable}. The iterator's 278 * {@code hasNext()} method returns {@code true} until {@code iterable} is 279 * empty. 280 * 281 * <p><b>Warning:</b> Typical uses of the resulting iterator may produce an 282 * infinite loop. You should use an explicit {@code break} or be certain that 283 * you will eventually remove all the elements. 284 * 285 * <p>To cycle over the iterable {@code n} times, use the following: 286 * {@code Iterables.concat(Collections.nCopies(n, iterable))} 287 */ 288 public static <T> Iterable<T> cycle(final Iterable<T> iterable) { 289 checkNotNull(iterable); 290 return new Iterable<T>() { 291 public Iterator<T> iterator() { 292 return Iterators.cycle(iterable); 293 } 294 @Override public String toString() { 295 return iterable.toString() + " (cycled)"; 296 } 297 }; 298 } 299 300 /** 301 * Returns an iterable whose iterators cycle indefinitely over the provided 302 * elements. 303 * 304 * <p>After {@code remove} is invoked on a generated iterator, the removed 305 * element will no longer appear in either that iterator or any other iterator 306 * created from the same source iterable. That is, this method behaves exactly 307 * as {@code Iterables.cycle(Lists.newArrayList(elements))}. The iterator's 308 * {@code hasNext} method returns {@code true} until all of the original 309 * elements have been removed. 310 * 311 * <p><b>Warning:</b> Typical uses of the resulting iterator may produce an 312 * infinite loop. You should use an explicit {@code break} or be certain that 313 * you will eventually remove all the elements. 314 * 315 * <p>To cycle over the elements {@code n} times, use the following: 316 * {@code Iterables.concat(Collections.nCopies(n, Arrays.asList(elements)))} 317 */ 318 public static <T> Iterable<T> cycle(T... elements) { 319 return cycle(Lists.newArrayList(elements)); 320 } 321 322 /** 323 * Combines two iterables into a single iterable. The returned iterable has an 324 * iterator that traverses the elements in {@code a}, followed by the elements 325 * in {@code b}. The source iterators are not polled until necessary. 326 * 327 * <p>The returned iterable's iterator supports {@code remove()} when the 328 * corresponding input iterator supports it. 329 */ 330 @SuppressWarnings("unchecked") 331 public static <T> Iterable<T> concat( 332 Iterable<? extends T> a, Iterable<? extends T> b) { 333 checkNotNull(a); 334 checkNotNull(b); 335 return concat(Arrays.asList(a, b)); 336 } 337 338 /** 339 * Combines three iterables into a single iterable. The returned iterable has 340 * an iterator that traverses the elements in {@code a}, followed by the 341 * elements in {@code b}, followed by the elements in {@code c}. The source 342 * iterators are not polled until necessary. 343 * 344 * <p>The returned iterable's iterator supports {@code remove()} when the 345 * corresponding input iterator supports it. 346 */ 347 @SuppressWarnings("unchecked") 348 public static <T> Iterable<T> concat(Iterable<? extends T> a, 349 Iterable<? extends T> b, Iterable<? extends T> c) { 350 checkNotNull(a); 351 checkNotNull(b); 352 checkNotNull(c); 353 return concat(Arrays.asList(a, b, c)); 354 } 355 356 /** 357 * Combines four iterables into a single iterable. The returned iterable has 358 * an iterator that traverses the elements in {@code a}, followed by the 359 * elements in {@code b}, followed by the elements in {@code c}, followed by 360 * the elements in {@code d}. The source iterators are not polled until 361 * necessary. 362 * 363 * <p>The returned iterable's iterator supports {@code remove()} when the 364 * corresponding input iterator supports it. 365 */ 366 @SuppressWarnings("unchecked") 367 public static <T> Iterable<T> concat(Iterable<? extends T> a, 368 Iterable<? extends T> b, Iterable<? extends T> c, 369 Iterable<? extends T> d) { 370 checkNotNull(a); 371 checkNotNull(b); 372 checkNotNull(c); 373 checkNotNull(d); 374 return concat(Arrays.asList(a, b, c, d)); 375 } 376 377 /** 378 * Combines multiple iterables into a single iterable. The returned iterable 379 * has an iterator that traverses the elements of each iterable in 380 * {@code inputs}. The input iterators are not polled until necessary. 381 * 382 * <p>The returned iterable's iterator supports {@code remove()} when the 383 * corresponding input iterator supports it. 384 * 385 * @throws NullPointerException if any of the provided iterables is null 386 */ 387 public static <T> Iterable<T> concat(Iterable<? extends T>... inputs) { 388 return concat(ImmutableList.copyOf(inputs)); 389 } 390 391 /** 392 * Combines multiple iterables into a single iterable. The returned iterable 393 * has an iterator that traverses the elements of each iterable in 394 * {@code inputs}. The input iterators are not polled until necessary. 395 * 396 * <p>The returned iterable's iterator supports {@code remove()} when the 397 * corresponding input iterator supports it. The methods of the returned 398 * iterable may throw {@code NullPointerException} if any of the input 399 * iterators are null. 400 */ 401 public static <T> Iterable<T> concat( 402 Iterable<? extends Iterable<? extends T>> inputs) { 403 /* 404 * Hint: if you let A represent Iterable<? extends T> and B represent 405 * Iterator<? extends T>, then this Function would look simply like: 406 * 407 * Function<A, B> function = new Function<A, B> { 408 * public B apply(A from) { 409 * return from.iterator(); 410 * } 411 * } 412 * 413 * TODO: there may be a better way to do this. 414 */ 415 416 Function<Iterable<? extends T>, Iterator<? extends T>> function 417 = new Function<Iterable<? extends T>, Iterator<? extends T>>() { 418 public Iterator<? extends T> apply(Iterable<? extends T> from) { 419 return from.iterator(); 420 } 421 }; 422 final Iterable<Iterator<? extends T>> iterators 423 = transform(inputs, function); 424 return new IterableWithToString<T>() { 425 public Iterator<T> iterator() { 426 return Iterators.concat(iterators.iterator()); 427 } 428 }; 429 } 430 431 /** 432 * Divides an iterable into unmodifiable sublists of the given size (the final 433 * iterable may be smaller). For example, partitioning an iterable containing 434 * {@code [a, b, c, d, e]} with a partition size of 3 yields {@code 435 * [[a, b, c], [d, e]]} -- an outer iterable containing two inner lists of 436 * three and two elements, all in the original order. 437 * 438 * <p>Iterators returned by the returned iterable do not support the {@link 439 * Iterator#remove()} method. The returned lists implement {@link 440 * RandomAccess}, whether or not the input list does. 441 * 442 * <p><b>Note:</b> if {@code iterable} is a {@link List}, use {@link 443 * Lists#partition(List, int)} instead. 444 * 445 * @param iterable the iterable to return a partitioned view of 446 * @param size the desired size of each partition (the last may be smaller) 447 * @return an iterable of unmodifiable lists containing the elements of {@code 448 * iterable} divided into partitions 449 * @throws IllegalArgumentException if {@code size} is nonpositive 450 */ 451 public static <T> Iterable<List<T>> partition( 452 final Iterable<T> iterable, final int size) { 453 checkNotNull(iterable); 454 checkArgument(size > 0); 455 return new IterableWithToString<List<T>>() { 456 public Iterator<List<T>> iterator() { 457 return Iterators.partition(iterable.iterator(), size); 458 } 459 }; 460 } 461 462 /** 463 * Divides an iterable into unmodifiable sublists of the given size, padding 464 * the final iterable with null values if necessary. For example, partitioning 465 * an iterable containing {@code [a, b, c, d, e]} with a partition size of 3 466 * yields {@code [[a, b, c], [d, e, null]]} -- an outer iterable containing 467 * two inner lists of three elements each, all in the original order. 468 * 469 * <p>Iterators returned by the returned iterable do not support the {@link 470 * Iterator#remove()} method. 471 * 472 * @param iterable the iterable to return a partitioned view of 473 * @param size the desired size of each partition 474 * @return an iterable of unmodifiable lists containing the elements of {@code 475 * iterable} divided into partitions (the final iterable may have 476 * trailing null elements) 477 * @throws IllegalArgumentException if {@code size} is nonpositive 478 */ 479 public static <T> Iterable<List<T>> paddedPartition( 480 final Iterable<T> iterable, final int size) { 481 checkNotNull(iterable); 482 checkArgument(size > 0); 483 return new IterableWithToString<List<T>>() { 484 public Iterator<List<T>> iterator() { 485 return Iterators.paddedPartition(iterable.iterator(), size); 486 } 487 }; 488 } 489 490 /** 491 * Returns the elements of {@code unfiltered} that satisfy a predicate. The 492 * resulting iterable's iterator does not support {@code remove()}. 493 */ 494 public static <T> Iterable<T> filter( 495 final Iterable<T> unfiltered, final Predicate<? super T> predicate) { 496 checkNotNull(unfiltered); 497 checkNotNull(predicate); 498 return new IterableWithToString<T>() { 499 public Iterator<T> iterator() { 500 return Iterators.filter(unfiltered.iterator(), predicate); 501 } 502 }; 503 } 504 505 /** 506 * Returns all instances of class {@code type} in {@code unfiltered}. The 507 * returned iterable has elements whose class is {@code type} or a subclass of 508 * {@code type}. The returned iterable's iterator does not support 509 * {@code remove()}. 510 * 511 * @param unfiltered an iterable containing objects of any type 512 * @param type the type of elements desired 513 * @return an unmodifiable iterable containing all elements of the original 514 * iterable that were of the requested type 515 */ 516 @GwtIncompatible("Class.isInstance") 517 public static <T> Iterable<T> filter( 518 final Iterable<?> unfiltered, final Class<T> type) { 519 checkNotNull(unfiltered); 520 checkNotNull(type); 521 return new IterableWithToString<T>() { 522 public Iterator<T> iterator() { 523 return Iterators.filter(unfiltered.iterator(), type); 524 } 525 }; 526 } 527 528 /** 529 * Returns {@code true} if one or more elements in {@code iterable} satisfy 530 * the predicate. 531 */ 532 public static <T> boolean any( 533 Iterable<T> iterable, Predicate<? super T> predicate) { 534 return Iterators.any(iterable.iterator(), predicate); 535 } 536 537 /** 538 * Returns {@code true} if every element in {@code iterable} satisfies the 539 * predicate. If {@code iterable} is empty, {@code true} is returned. 540 */ 541 public static <T> boolean all( 542 Iterable<T> iterable, Predicate<? super T> predicate) { 543 return Iterators.all(iterable.iterator(), predicate); 544 } 545 546 /** 547 * Returns the first element in {@code iterable} that satisfies the given 548 * predicate. 549 * 550 * @throws NoSuchElementException if no element in {@code iterable} matches 551 * the given predicate 552 */ 553 public static <T> T find(Iterable<T> iterable, 554 Predicate<? super T> predicate) { 555 return Iterators.find(iterable.iterator(), predicate); 556 } 557 558 /** 559 * Returns the index in {@code iterable} of the first element that satisfies 560 * the provided {@code predicate}, or {@code -1} if the Iterable has no such 561 * elements. 562 * 563 * <p>More formally, returns the lowest index {@code i} such that 564 * {@code predicate.apply(Iterables.get(iterable, i))} is {@code true} or 565 * {@code -1} if there is no such index. 566 * 567 * @since 2 568 */ 569 public static <T> int indexOf( 570 Iterable<T> iterable, Predicate<? super T> predicate) { 571 return Iterators.indexOf(iterable.iterator(), predicate); 572 } 573 574 /** 575 * Returns an iterable that applies {@code function} to each element of {@code 576 * fromIterable}. 577 * 578 * <p>The returned iterable's iterator supports {@code remove()} if the 579 * provided iterator does. After a successful {@code remove()} call, 580 * {@code fromIterable} no longer contains the corresponding element. 581 */ 582 public static <F, T> Iterable<T> transform(final Iterable<F> fromIterable, 583 final Function<? super F, ? extends T> function) { 584 checkNotNull(fromIterable); 585 checkNotNull(function); 586 return new IterableWithToString<T>() { 587 public Iterator<T> iterator() { 588 return Iterators.transform(fromIterable.iterator(), function); 589 } 590 }; 591 } 592 593 /** 594 * Returns the element at the specified position in an iterable. 595 * 596 * @param position position of the element to return 597 * @return the element at the specified position in {@code iterable} 598 * @throws IndexOutOfBoundsException if {@code position} is negative or 599 * greater than or equal to the size of {@code iterable} 600 */ 601 public static <T> T get(Iterable<T> iterable, int position) { 602 checkNotNull(iterable); 603 if (iterable instanceof List) { 604 return ((List<T>) iterable).get(position); 605 } 606 607 if (iterable instanceof Collection) { 608 // Can check both ends 609 Collection<T> collection = (Collection<T>) iterable; 610 Preconditions.checkElementIndex(position, collection.size()); 611 } else { 612 // Can only check the lower end 613 checkNonnegativeIndex(position); 614 } 615 return Iterators.get(iterable.iterator(), position); 616 } 617 618 private static void checkNonnegativeIndex(int position) { 619 if (position < 0) { 620 throw new IndexOutOfBoundsException( 621 "position cannot be negative: " + position); 622 } 623 } 624 625 /** 626 * Returns the element at the specified position in an iterable or a default 627 * value otherwise. 628 * 629 * @param position position of the element to return 630 * @param defaultValue the default value to return if {@code position} is 631 * greater than or equal to the size of the iterable 632 * @return the element at the specified position in {@code iterable} or 633 * {@code defaultValue} if {@code iterable} contains fewer than 634 * {@code position + 1} elements. 635 * @throws IndexOutOfBoundsException if {@code position} is negative 636 * @since 4 637 */ 638 @Beta 639 public static <T> T get(Iterable<T> iterable, int position, 640 @Nullable T defaultValue) { 641 checkNotNull(iterable); 642 checkNonnegativeIndex(position); 643 644 try { 645 return get(iterable, position); 646 } catch (IndexOutOfBoundsException e) { 647 return defaultValue; 648 } 649 } 650 651 /** 652 * Returns the last element of {@code iterable}. 653 * 654 * @return the last element of {@code iterable} 655 * @throws NoSuchElementException if the iterable has no elements 656 */ 657 public static <T> T getLast(Iterable<T> iterable) { 658 if (iterable instanceof List) { 659 List<T> list = (List<T>) iterable; 660 // TODO: Support a concurrent list whose size changes while this method 661 // is running. 662 if (list.isEmpty()) { 663 throw new NoSuchElementException(); 664 } 665 return getLastInNonemptyList(list); 666 } 667 668 // TODO: consider whether this "optimization" is worthwhile. Users with 669 // SortedSets tend to know they are SortedSets and probably would not 670 // call this method. 671 if (iterable instanceof SortedSet) { 672 SortedSet<T> sortedSet = (SortedSet<T>) iterable; 673 return sortedSet.last(); 674 } 675 676 return Iterators.getLast(iterable.iterator()); 677 } 678 679 /** 680 * Returns the last element of {@code iterable} or {@code defaultValue} if 681 * the iterable is empty. 682 * 683 * @param defaultValue the value to return if {@code iterable} is empty 684 * @return the last element of {@code iterable} or the default value 685 * @since 3 686 */ 687 public static <T> T getLast(Iterable<T> iterable, @Nullable T defaultValue) { 688 if (iterable instanceof Collection) { 689 Collection<T> collection = (Collection<T>) iterable; 690 if (collection.isEmpty()) { 691 return defaultValue; 692 } 693 } 694 695 if (iterable instanceof List) { 696 List<T> list = (List<T>) iterable; 697 return getLastInNonemptyList(list); 698 } 699 700 // TODO: consider whether this "optimization" is worthwhile. Users with 701 // SortedSets tend to know they are SortedSets and probably would not 702 // call this method. 703 if (iterable instanceof SortedSet) { 704 SortedSet<T> sortedSet = (SortedSet<T>) iterable; 705 return sortedSet.last(); 706 } 707 708 return Iterators.getLast(iterable.iterator(), defaultValue); 709 } 710 711 private static <T> T getLastInNonemptyList(List<T> list) { 712 return list.get(list.size() - 1); 713 } 714 715 /** 716 * Returns a view of {@code iterable} that skips its first 717 * {@code numberToSkip} elements. If {@code iterable} contains fewer than 718 * {@code numberToSkip} elements, the returned iterable skips all of its 719 * elements. 720 * 721 * <p>Modifications to the underlying {@link Iterable} before a call to 722 * {@code iterator()} are reflected in the returned iterator. That is, the 723 * iterator skips the first {@code numberToSkip} elements that exist when the 724 * {@code Iterator} is created, not when {@code skip()} is called. 725 * 726 * <p>The returned iterable's iterator supports {@code remove()} if the 727 * iterator of the underlying iterable supports it. Note that it is 728 * <i>not</i> possible to delete the last skipped element by immediately 729 * calling {@code remove()} on that iterator, as the {@code Iterator} 730 * contract states that a call to {@code remove()} before a call to 731 * {@code next()} will throw an {@link IllegalStateException}. 732 * 733 * @since 3 734 */ 735 @Beta // naming issue 736 public static <T> Iterable<T> skip(final Iterable<T> iterable, 737 final int numberToSkip) { 738 checkNotNull(iterable); 739 checkArgument(numberToSkip >= 0, "number to skip cannot be negative"); 740 741 if (iterable instanceof List) { 742 final List<T> list = (List<T>) iterable; 743 return new IterableWithToString<T>() { 744 public Iterator<T> iterator() { 745 // TODO: Support a concurrent list whose size changes while this 746 // method is running. 747 return (numberToSkip >= list.size()) 748 ? Iterators.<T>emptyIterator() 749 : list.subList(numberToSkip, list.size()).iterator(); 750 } 751 }; 752 } 753 754 return new IterableWithToString<T>() { 755 public Iterator<T> iterator() { 756 final Iterator<T> iterator = iterable.iterator(); 757 758 Iterators.skip(iterator, numberToSkip); 759 760 /* 761 * We can't just return the iterator because an immediate call to its 762 * remove() method would remove one of the skipped elements instead of 763 * throwing an IllegalStateException. 764 */ 765 return new Iterator<T>() { 766 boolean atStart = true; 767 768 public boolean hasNext() { 769 return iterator.hasNext(); 770 } 771 772 public T next() { 773 if (!hasNext()) { 774 throw new NoSuchElementException(); 775 } 776 777 try { 778 return iterator.next(); 779 } finally { 780 atStart = false; 781 } 782 } 783 784 public void remove() { 785 if (atStart) { 786 throw new IllegalStateException(); 787 } 788 iterator.remove(); 789 } 790 }; 791 } 792 }; 793 } 794 795 /** 796 * Creates an iterable with the first {@code limitSize} elements of the given 797 * iterable. If the original iterable does not contain that many elements, the 798 * returned iterator will have the same behavior as the original iterable. The 799 * returned iterable's iterator supports {@code remove()} if the original 800 * iterator does. 801 * 802 * @param iterable the iterable to limit 803 * @param limitSize the maximum number of elements in the returned iterator 804 * @throws IllegalArgumentException if {@code limitSize} is negative 805 * @since 3 806 */ 807 @Beta // naming issue 808 public static <T> Iterable<T> limit( 809 final Iterable<T> iterable, final int limitSize) { 810 checkNotNull(iterable); 811 checkArgument(limitSize >= 0, "limit is negative"); 812 return new IterableWithToString<T>() { 813 public Iterator<T> iterator() { 814 return Iterators.limit(iterable.iterator(), limitSize); 815 } 816 }; 817 } 818 819 /** 820 * Returns a view of the supplied iterable that wraps each generated 821 * {@link Iterator} through {@link Iterators#consumingIterator(Iterator)}. 822 * 823 * @param iterable the iterable to wrap 824 * @return a view of the supplied iterable that wraps each generated iterator 825 * through {@link Iterators#consumingIterator(Iterator)} 826 * 827 * @see Iterators#consumingIterator(Iterator) 828 * @since 2 829 */ 830 @Beta 831 public static <T> Iterable<T> consumingIterable(final Iterable<T> iterable) { 832 checkNotNull(iterable); 833 return new Iterable<T>() { 834 public Iterator<T> iterator() { 835 return Iterators.consumingIterator(iterable.iterator()); 836 } 837 }; 838 } 839 840 // Methods only in Iterables, not in Iterators 841 842 /** 843 * Adapts a list to an iterable with reversed iteration order. It is 844 * especially useful in foreach-style loops: <pre class="code"> {@code 845 * 846 * List<String> mylist = ... 847 * for (String str : Iterables.reverse(mylist)) { 848 * ... 849 * }}</pre> 850 * 851 * There is no corresponding method in {@link Iterators}, since {@link 852 * Iterable#iterator} can simply be invoked on the result of calling this 853 * method. 854 * 855 * @return an iterable with the same elements as the list, in reverse 856 */ 857 public static <T> Iterable<T> reverse(final List<T> list) { 858 checkNotNull(list); 859 return new IterableWithToString<T>() { 860 public Iterator<T> iterator() { 861 final ListIterator<T> listIter = list.listIterator(list.size()); 862 return new Iterator<T>() { 863 public boolean hasNext() { 864 return listIter.hasPrevious(); 865 } 866 public T next() { 867 return listIter.previous(); 868 } 869 public void remove() { 870 listIter.remove(); 871 } 872 }; 873 } 874 }; 875 } 876 877 /** 878 * Determines if the given iterable contains no elements. 879 * 880 * <p>There is no precise {@link Iterator} equivalent to this method, since 881 * one can only ask an iterator whether it has any elements <i>remaining</i> 882 * (which one does using {@link Iterator#hasNext}). 883 * 884 * @return {@code true} if the iterable contains no elements 885 */ 886 public static <T> boolean isEmpty(Iterable<T> iterable) { 887 return !iterable.iterator().hasNext(); 888 } 889 890 // Non-public 891 892 /** 893 * Removes the specified element from the specified iterable. 894 * 895 * <p>This method iterates over the iterable, checking each element returned 896 * by the iterator in turn to see if it equals the object {@code o}. If they 897 * are equal, it is removed from the iterable with the iterator's 898 * {@code remove} method. At most one element is removed, even if the iterable 899 * contains multiple members that equal {@code o}. 900 * 901 * <p><b>Warning</b>: Do not use this method for a collection, such as a 902 * {@link HashSet}, that has a fast {@code remove} method. 903 * 904 * @param iterable the iterable from which to remove 905 * @param o an element to remove from the collection 906 * @return {@code true} if the iterable changed as a result 907 * @throws UnsupportedOperationException if the iterator does not support the 908 * {@code remove} method and the iterable contains the object 909 */ 910 static boolean remove(Iterable<?> iterable, @Nullable Object o) { 911 Iterator<?> i = iterable.iterator(); 912 while (i.hasNext()) { 913 if (Objects.equal(i.next(), o)) { 914 i.remove(); 915 return true; 916 } 917 } 918 return false; 919 } 920 921 abstract static class IterableWithToString<E> implements Iterable<E> { 922 @Override public String toString() { 923 return Iterables.toString(this); 924 } 925 } 926 }