CollectionUtils.java revision 6186821cb13f4ac7ff50950c813394367e021eae
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
17package libcore.util;
18
19import java.lang.ref.Reference;
20import java.util.Iterator;
21
22public final class CollectionUtils {
23    private CollectionUtils() {}
24
25    /**
26     * Returns an iterator over the values referenced by the elements of {@code
27     * iterable}.
28     *
29     * @param trim true to remove reference objects from the iterable after
30     *     their referenced values have been cleared.
31     */
32    public static <T> Iterable<T> dereferenceIterable(
33            final Iterable<? extends Reference<T>> iterable, final boolean trim) {
34        return new Iterable<T>() {
35            public Iterator<T> iterator() {
36                return new Iterator<T>() {
37                    private final Iterator<? extends Reference<T>> delegate = iterable.iterator();
38                    private boolean removeIsOkay;
39                    private T next;
40
41                    private void computeNext() {
42                        removeIsOkay = false;
43                        while (next == null && delegate.hasNext()) {
44                            next = delegate.next().get();
45                            if (trim && next == null) {
46                                delegate.remove();
47                            }
48                        }
49                    }
50
51                    @Override public boolean hasNext() {
52                        computeNext();
53                        return next != null;
54                    }
55
56                    @Override public T next() {
57                        if (!hasNext()) {
58                            throw new IllegalStateException();
59                        }
60                        T result = next;
61                        removeIsOkay = true;
62                        next = null;
63                        return result;
64                    }
65
66                    public void remove() {
67                        if (!removeIsOkay) {
68                            throw new IllegalStateException();
69                        }
70                        delegate.remove();
71                    }
72                };
73            }
74        };
75    }
76}
77