1be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson/* 2be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * Copyright (C) 2010 The Android Open Source Project 3be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * 4be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 5be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * you may not use this file except in compliance with the License. 6be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * You may obtain a copy of the License at 7be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * 8be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 9be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * 10be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * Unless required by applicable law or agreed to in writing, software 11be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 12be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * See the License for the specific language governing permissions and 14be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * limitations under the License. 15be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson */ 16be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson 176186821cb13f4ac7ff50950c813394367e021eaeJesse Wilsonpackage libcore.util; 18be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson 19be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilsonimport java.lang.ref.Reference; 200843c022f443b5c4a8ea4d298c8b12147989ec92Jesse Wilsonimport java.util.ArrayList; 210843c022f443b5c4a8ea4d298c8b12147989ec92Jesse Wilsonimport java.util.Collections; 220843c022f443b5c4a8ea4d298c8b12147989ec92Jesse Wilsonimport java.util.Comparator; 23be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilsonimport java.util.Iterator; 240843c022f443b5c4a8ea4d298c8b12147989ec92Jesse Wilsonimport java.util.List; 25be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson 26be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilsonpublic final class CollectionUtils { 27be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson private CollectionUtils() {} 28be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson 29be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson /** 30be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * Returns an iterator over the values referenced by the elements of {@code 31be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * iterable}. 32be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * 33be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * @param trim true to remove reference objects from the iterable after 34be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * their referenced values have been cleared. 35be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson */ 36be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson public static <T> Iterable<T> dereferenceIterable( 37be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson final Iterable<? extends Reference<T>> iterable, final boolean trim) { 38be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson return new Iterable<T>() { 39be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson public Iterator<T> iterator() { 40be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson return new Iterator<T>() { 41be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson private final Iterator<? extends Reference<T>> delegate = iterable.iterator(); 42be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson private boolean removeIsOkay; 43be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson private T next; 44be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson 45be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson private void computeNext() { 46be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson removeIsOkay = false; 47be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson while (next == null && delegate.hasNext()) { 48be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson next = delegate.next().get(); 49be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson if (trim && next == null) { 50be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson delegate.remove(); 51be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson } 52be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson } 53be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson } 54be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson 55be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson @Override public boolean hasNext() { 56be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson computeNext(); 57be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson return next != null; 58be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson } 59be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson 60be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson @Override public T next() { 61be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson if (!hasNext()) { 62be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson throw new IllegalStateException(); 63be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson } 64be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson T result = next; 65be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson removeIsOkay = true; 66be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson next = null; 67be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson return result; 68be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson } 69be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson 70be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson public void remove() { 71be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson if (!removeIsOkay) { 72be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson throw new IllegalStateException(); 73be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson } 74be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson delegate.remove(); 75be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson } 76be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson }; 77be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson } 78be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson }; 79be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson } 800843c022f443b5c4a8ea4d298c8b12147989ec92Jesse Wilson 810843c022f443b5c4a8ea4d298c8b12147989ec92Jesse Wilson /** 82f16edfe125c261e7f4e5cff52c0b9c923d9f7fe6Jesse Wilson * Sorts and removes duplicate elements from {@code list}. This method does 83f16edfe125c261e7f4e5cff52c0b9c923d9f7fe6Jesse Wilson * not use {@link Object#equals}: only the comparator defines equality. 840843c022f443b5c4a8ea4d298c8b12147989ec92Jesse Wilson */ 85f16edfe125c261e7f4e5cff52c0b9c923d9f7fe6Jesse Wilson public static <T> void removeDuplicates(List<T> list, Comparator<? super T> comparator) { 860843c022f443b5c4a8ea4d298c8b12147989ec92Jesse Wilson Collections.sort(list, comparator); 87f16edfe125c261e7f4e5cff52c0b9c923d9f7fe6Jesse Wilson int j = 1; 88f16edfe125c261e7f4e5cff52c0b9c923d9f7fe6Jesse Wilson for (int i = 1; i < list.size(); i++) { 89f16edfe125c261e7f4e5cff52c0b9c923d9f7fe6Jesse Wilson if (comparator.compare(list.get(j - 1), list.get(i)) != 0) { 90f16edfe125c261e7f4e5cff52c0b9c923d9f7fe6Jesse Wilson T object = list.get(i); 91f16edfe125c261e7f4e5cff52c0b9c923d9f7fe6Jesse Wilson list.set(j++, object); 920843c022f443b5c4a8ea4d298c8b12147989ec92Jesse Wilson } 930843c022f443b5c4a8ea4d298c8b12147989ec92Jesse Wilson } 94f16edfe125c261e7f4e5cff52c0b9c923d9f7fe6Jesse Wilson if (j < list.size()) { 95f16edfe125c261e7f4e5cff52c0b9c923d9f7fe6Jesse Wilson list.subList(j, list.size()).clear(); 96f16edfe125c261e7f4e5cff52c0b9c923d9f7fe6Jesse Wilson } 970843c022f443b5c4a8ea4d298c8b12147989ec92Jesse Wilson } 98be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson} 99