1 /* 2 * Copyright (C) 2010 The Android Open Source Project 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 libcore.util; 18 19 import java.lang.ref.Reference; 20 import java.util.ArrayList; 21 import java.util.Collections; 22 import java.util.Comparator; 23 import java.util.Iterator; 24 import java.util.List; 25 26 public final class CollectionUtils { CollectionUtils()27 private CollectionUtils() {} 28 29 /** 30 * Returns an iterator over the values referenced by the elements of {@code 31 * iterable}. 32 * 33 * @param trim true to remove reference objects from the iterable after 34 * their referenced values have been cleared. 35 */ dereferenceIterable( final Iterable<? extends Reference<T>> iterable, final boolean trim)36 public static <T> Iterable<T> dereferenceIterable( 37 final Iterable<? extends Reference<T>> iterable, final boolean trim) { 38 return new Iterable<T>() { 39 public Iterator<T> iterator() { 40 return new Iterator<T>() { 41 private final Iterator<? extends Reference<T>> delegate = iterable.iterator(); 42 private boolean removeIsOkay; 43 private T next; 44 45 private void computeNext() { 46 removeIsOkay = false; 47 while (next == null && delegate.hasNext()) { 48 next = delegate.next().get(); 49 if (trim && next == null) { 50 delegate.remove(); 51 } 52 } 53 } 54 55 @Override public boolean hasNext() { 56 computeNext(); 57 return next != null; 58 } 59 60 @Override public T next() { 61 if (!hasNext()) { 62 throw new IllegalStateException(); 63 } 64 T result = next; 65 removeIsOkay = true; 66 next = null; 67 return result; 68 } 69 70 public void remove() { 71 if (!removeIsOkay) { 72 throw new IllegalStateException(); 73 } 74 delegate.remove(); 75 } 76 }; 77 } 78 }; 79 } 80 81 /** 82 * Sorts and removes duplicate elements from {@code list}. This method does 83 * not use {@link Object#equals}: only the comparator defines equality. 84 */ 85 public static <T> void removeDuplicates(List<T> list, Comparator<? super T> comparator) { 86 Collections.sort(list, comparator); 87 int j = 1; 88 for (int i = 1; i < list.size(); i++) { 89 if (comparator.compare(list.get(j - 1), list.get(i)) != 0) { 90 T object = list.get(i); 91 list.set(j++, object); 92 } 93 } 94 if (j < list.size()) { 95 list.subList(j, list.size()).clear(); 96 } 97 } 98 } 99