12290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn/*
2ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * Copyright 2018 The Android Open Source Project
32290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn *
42290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
52290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn * you may not use this file except in compliance with the License.
62290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn * You may obtain a copy of the License at
72290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn *
82290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
92290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn *
102290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn * Unless required by applicable law or agreed to in writing, software
112290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
122290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn * See the License for the specific language governing permissions and
142290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn * limitations under the License.
152290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn */
162290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
17ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.collection;
182290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
192290993eddf5262a8df7fc9478daed52401e325aDianne Hackbornimport java.lang.reflect.Array;
202290993eddf5262a8df7fc9478daed52401e325aDianne Hackbornimport java.util.Collection;
212290993eddf5262a8df7fc9478daed52401e325aDianne Hackbornimport java.util.Iterator;
222290993eddf5262a8df7fc9478daed52401e325aDianne Hackbornimport java.util.Map;
23b6e9d617ea32dc83840a030982a97a20f7889010Tobias Thiererimport java.util.NoSuchElementException;
242290993eddf5262a8df7fc9478daed52401e325aDianne Hackbornimport java.util.Set;
252290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
262290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn/**
272290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn * Helper for writing standard Java collection interfaces to a data
282290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn * structure like {@link ArrayMap}.
292290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn */
302290993eddf5262a8df7fc9478daed52401e325aDianne Hackbornabstract class MapCollections<K, V> {
312290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    EntrySet mEntrySet;
322290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    KeySet mKeySet;
332290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    ValuesCollection mValues;
342290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
352290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    final class ArrayIterator<T> implements Iterator<T> {
362290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        final int mOffset;
372290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        int mSize;
382290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        int mIndex;
392290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        boolean mCanRemove = false;
402290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
412290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        ArrayIterator(int offset) {
422290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mOffset = offset;
432290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mSize = colGetSize();
442290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
452290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
462290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
472290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean hasNext() {
482290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return mIndex < mSize;
492290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
502290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
512290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
522290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public T next() {
53b6e9d617ea32dc83840a030982a97a20f7889010Tobias Thierer            if (!hasNext()) throw new NoSuchElementException();
542290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            Object res = colGetEntry(mIndex, mOffset);
552290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mIndex++;
562290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mCanRemove = true;
572290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return (T)res;
582290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
592290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
602290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
612290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public void remove() {
622290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            if (!mCanRemove) {
632290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                throw new IllegalStateException();
642290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
652290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mIndex--;
662290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mSize--;
672290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mCanRemove = false;
682290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            colRemoveAt(mIndex);
692290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
702290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    }
712290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
722290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    final class MapIterator implements Iterator<Map.Entry<K, V>>, Map.Entry<K, V> {
732290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        int mEnd;
742290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        int mIndex;
752290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        boolean mEntryValid = false;
762290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
772290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        MapIterator() {
782290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mEnd = colGetSize() - 1;
792290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mIndex = -1;
802290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
812290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
822290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
832290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean hasNext() {
842290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return mIndex < mEnd;
852290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
862290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
872290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
882290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public Map.Entry<K, V> next() {
89b6e9d617ea32dc83840a030982a97a20f7889010Tobias Thierer            if (!hasNext()) throw new NoSuchElementException();
902290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mIndex++;
912290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mEntryValid = true;
922290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return this;
932290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
942290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
952290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
962290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public void remove() {
972290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            if (!mEntryValid) {
982290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                throw new IllegalStateException();
992290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
100138e0db47a8fe52d96d38c7be3fe9d2ad7f4083bAdam Lesinski            colRemoveAt(mIndex);
1012290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mIndex--;
1022290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mEnd--;
1032290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mEntryValid = false;
1042290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
1052290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
1062290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
1072290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public K getKey() {
1082290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            if (!mEntryValid) {
1092290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                throw new IllegalStateException(
1102290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                        "This container does not support retaining Map.Entry objects");
1112290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
1122290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return (K)colGetEntry(mIndex, 0);
1132290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
1142290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
1152290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
1162290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public V getValue() {
1172290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            if (!mEntryValid) {
1182290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                throw new IllegalStateException(
1192290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                        "This container does not support retaining Map.Entry objects");
1202290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
1212290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return (V)colGetEntry(mIndex, 1);
1222290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
1232290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
1242290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
1252290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public V setValue(V object) {
1262290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            if (!mEntryValid) {
1272290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                throw new IllegalStateException(
1282290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                        "This container does not support retaining Map.Entry objects");
1292290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
1302290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return colSetValue(mIndex, object);
1312290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
1322290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
1332290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
1345211222f71426ccfc1f2cca9f5f6bb89c61c9ed5Jake Wharton        public boolean equals(Object o) {
1352290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            if (!mEntryValid) {
1362290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                throw new IllegalStateException(
1372290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                        "This container does not support retaining Map.Entry objects");
1382290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
1392290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            if (!(o instanceof Map.Entry)) {
1402290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                return false;
1412290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
1422290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
1432290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return ContainerHelpers.equal(e.getKey(), colGetEntry(mIndex, 0))
1442290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                    && ContainerHelpers.equal(e.getValue(), colGetEntry(mIndex, 1));
1452290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
1462290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
1472290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
1485211222f71426ccfc1f2cca9f5f6bb89c61c9ed5Jake Wharton        public int hashCode() {
1492290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            if (!mEntryValid) {
1502290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                throw new IllegalStateException(
1512290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                        "This container does not support retaining Map.Entry objects");
1522290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
1532290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            final Object key = colGetEntry(mIndex, 0);
1542290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            final Object value = colGetEntry(mIndex, 1);
1552290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return (key == null ? 0 : key.hashCode()) ^
1562290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                    (value == null ? 0 : value.hashCode());
1572290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
1582290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
1592290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
1605211222f71426ccfc1f2cca9f5f6bb89c61c9ed5Jake Wharton        public String toString() {
1612290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return getKey() + "=" + getValue();
1622290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
1632290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    }
1642290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
1652290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    final class EntrySet implements Set<Map.Entry<K, V>> {
1662290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
1672290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean add(Map.Entry<K, V> object) {
1682290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            throw new UnsupportedOperationException();
1692290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
1702290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
1712290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
1722290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean addAll(Collection<? extends Map.Entry<K, V>> collection) {
1732290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            int oldSize = colGetSize();
1742290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            for (Map.Entry<K, V> entry : collection) {
1752290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                colPut(entry.getKey(), entry.getValue());
1762290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
1772290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return oldSize != colGetSize();
1782290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
1792290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
1802290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
1812290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public void clear() {
1822290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            colClear();
1832290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
1842290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
1852290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
186d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        public boolean contains(Object o) {
187d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            if (!(o instanceof Map.Entry))
188d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                return false;
189d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
190d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            int index = colIndexOfKey(e.getKey());
191d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            if (index < 0) {
192d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                return false;
193d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            }
194d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            Object foundVal = colGetEntry(index, 1);
195d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            return ContainerHelpers.equal(foundVal, e.getValue());
1962290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
1972290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
1982290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
1992290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean containsAll(Collection<?> collection) {
200d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            Iterator<?> it = collection.iterator();
201d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            while (it.hasNext()) {
202d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                if (!contains(it.next())) {
203d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                    return false;
204d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                }
205d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            }
206d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            return true;
2072290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2082290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2092290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2102290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean isEmpty() {
2112290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return colGetSize() == 0;
2122290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2132290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2142290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2152290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public Iterator<Map.Entry<K, V>> iterator() {
2162290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return new MapIterator();
2172290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2182290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2192290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2202290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean remove(Object object) {
2212290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            throw new UnsupportedOperationException();
2222290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2232290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2242290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2252290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean removeAll(Collection<?> collection) {
2262290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            throw new UnsupportedOperationException();
2272290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2282290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2292290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2302290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean retainAll(Collection<?> collection) {
2312290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            throw new UnsupportedOperationException();
2322290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2332290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2342290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2352290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public int size() {
2362290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return colGetSize();
2372290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2382290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2392290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2402290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public Object[] toArray() {
2412290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            throw new UnsupportedOperationException();
2422290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2432290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2442290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2452290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public <T> T[] toArray(T[] array) {
2462290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            throw new UnsupportedOperationException();
2472290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
248d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn
249d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        @Override
250d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        public boolean equals(Object object) {
251d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            return equalsSetHelper(this, object);
252d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        }
253d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn
254d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        @Override
255d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        public int hashCode() {
256d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            int result = 0;
257d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            for (int i=colGetSize()-1; i>=0; i--) {
258d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                final Object key = colGetEntry(i, 0);
259d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                final Object value = colGetEntry(i, 1);
260d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                result += ( (key == null ? 0 : key.hashCode()) ^
261d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                        (value == null ? 0 : value.hashCode()) );
262d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            }
263d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            return result;
264d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        }
2652290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    };
2662290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2672290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    final class KeySet implements Set<K> {
2682290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2692290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2702290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean add(K object) {
2712290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            throw new UnsupportedOperationException();
2722290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2732290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2742290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2752290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean addAll(Collection<? extends K> collection) {
2762290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            throw new UnsupportedOperationException();
2772290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2782290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2792290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2802290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public void clear() {
2812290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            colClear();
2822290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2832290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2842290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2852290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean contains(Object object) {
2862290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return colIndexOfKey(object) >= 0;
2872290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2882290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2892290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2902290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean containsAll(Collection<?> collection) {
291d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            return containsAllHelper(colGetMap(), collection);
2922290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2932290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2942290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2952290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean isEmpty() {
2962290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return colGetSize() == 0;
2972290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2982290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2992290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3002290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public Iterator<K> iterator() {
3012290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return new ArrayIterator<K>(0);
3022290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
3032290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3042290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3052290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean remove(Object object) {
3062290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            int index = colIndexOfKey(object);
3072290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            if (index >= 0) {
3082290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                colRemoveAt(index);
3092290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                return true;
3102290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
3112290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return false;
3122290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
3132290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3142290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3152290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean removeAll(Collection<?> collection) {
3162290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return removeAllHelper(colGetMap(), collection);
3172290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
3182290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3192290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3202290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean retainAll(Collection<?> collection) {
3212290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return retainAllHelper(colGetMap(), collection);
3222290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
3232290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3242290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3252290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public int size() {
3262290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return colGetSize();
3272290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
3282290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3292290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3302290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public Object[] toArray() {
3317b4c91bb218ce476748fc3fcecc71694a240d8cbDianne Hackborn            return toArrayHelper(0);
3322290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
3332290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3342290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3352290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public <T> T[] toArray(T[] array) {
3367b4c91bb218ce476748fc3fcecc71694a240d8cbDianne Hackborn            return toArrayHelper(array, 0);
3372290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
338d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn
339d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        @Override
340d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        public boolean equals(Object object) {
341d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            return equalsSetHelper(this, object);
342d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        }
343d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn
344d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        @Override
345d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        public int hashCode() {
346d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            int result = 0;
347d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            for (int i=colGetSize()-1; i>=0; i--) {
348d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                Object obj = colGetEntry(i, 0);
349d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                result += obj == null ? 0 : obj.hashCode();
350d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            }
351d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            return result;
352d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        }
3532290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    };
3542290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3552290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    final class ValuesCollection implements Collection<V> {
3562290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3572290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3582290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean add(V object) {
3592290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            throw new UnsupportedOperationException();
3602290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
3612290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3622290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3632290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean addAll(Collection<? extends V> collection) {
3642290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            throw new UnsupportedOperationException();
3652290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
3662290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3672290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3682290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public void clear() {
3692290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            colClear();
3702290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
3712290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3722290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3732290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean contains(Object object) {
3742290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return colIndexOfValue(object) >= 0;
3752290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
3762290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3772290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3782290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean containsAll(Collection<?> collection) {
3792290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            Iterator<?> it = collection.iterator();
3802290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            while (it.hasNext()) {
3812290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                if (!contains(it.next())) {
3822290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                    return false;
3832290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                }
3842290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
3852290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return true;
3862290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
3872290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3882290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3892290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean isEmpty() {
3902290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return colGetSize() == 0;
3912290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
3922290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3932290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3942290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public Iterator<V> iterator() {
3952290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return new ArrayIterator<V>(1);
3962290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
3972290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3982290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3992290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean remove(Object object) {
4002290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            int index = colIndexOfValue(object);
4012290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            if (index >= 0) {
4022290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                colRemoveAt(index);
4032290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                return true;
4042290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
4052290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return false;
4062290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
4072290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
4082290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
4092290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean removeAll(Collection<?> collection) {
4102290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            int N = colGetSize();
4112290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            boolean changed = false;
4122290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            for (int i=0; i<N; i++) {
4132290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                Object cur = colGetEntry(i, 1);
4142290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                if (collection.contains(cur)) {
4152290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                    colRemoveAt(i);
4162290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                    i--;
4172290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                    N--;
4182290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                    changed = true;
4192290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                }
4202290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
4212290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return changed;
4222290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
4232290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
4242290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
4252290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean retainAll(Collection<?> collection) {
4262290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            int N = colGetSize();
4272290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            boolean changed = false;
4282290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            for (int i=0; i<N; i++) {
4292290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                Object cur = colGetEntry(i, 1);
4302290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                if (!collection.contains(cur)) {
4312290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                    colRemoveAt(i);
4322290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                    i--;
4332290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                    N--;
4342290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                    changed = true;
4352290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                }
4362290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
4372290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return changed;
4382290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
4392290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
4402290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
4412290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public int size() {
4422290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return colGetSize();
4432290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
4442290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
4452290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
4462290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public Object[] toArray() {
4472290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return toArrayHelper(1);
4482290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
4492290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
4502290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
4512290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public <T> T[] toArray(T[] array) {
4522290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return toArrayHelper(array, 1);
4532290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
4542290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    };
4552290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
4562290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    public static <K, V> boolean containsAllHelper(Map<K, V> map, Collection<?> collection) {
4572290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        Iterator<?> it = collection.iterator();
4582290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        while (it.hasNext()) {
4592290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            if (!map.containsKey(it.next())) {
4602290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                return false;
4612290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
4622290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
4632290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        return true;
4642290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    }
4652290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
4662290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    public static <K, V> boolean removeAllHelper(Map<K, V> map, Collection<?> collection) {
4672290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        int oldSize = map.size();
4682290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        Iterator<?> it = collection.iterator();
4692290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        while (it.hasNext()) {
4702290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            map.remove(it.next());
4712290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
4722290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        return oldSize != map.size();
4732290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    }
4742290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
4752290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    public static <K, V> boolean retainAllHelper(Map<K, V> map, Collection<?> collection) {
4762290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        int oldSize = map.size();
4772290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        Iterator<K> it = map.keySet().iterator();
4782290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        while (it.hasNext()) {
4792290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            if (!collection.contains(it.next())) {
4802290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                it.remove();
4812290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
4822290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
4832290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        return oldSize != map.size();
4842290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    }
4852290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
4862290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
4872290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    public Object[] toArrayHelper(int offset) {
4882290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        final int N = colGetSize();
4892290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        Object[] result = new Object[N];
4902290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        for (int i=0; i<N; i++) {
4912290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            result[i] = colGetEntry(i, offset);
4922290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
4932290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        return result;
4942290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    }
4952290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
4962290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    public <T> T[] toArrayHelper(T[] array, int offset) {
4972290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        final int N  = colGetSize();
4982290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        if (array.length < N) {
4992290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            @SuppressWarnings("unchecked") T[] newArray
5002290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                = (T[]) Array.newInstance(array.getClass().getComponentType(), N);
5012290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            array = newArray;
5022290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
5032290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        for (int i=0; i<N; i++) {
5042290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            array[i] = (T)colGetEntry(i, offset);
5052290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
5062290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        if (array.length > N) {
5072290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            array[N] = null;
5082290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
5092290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        return array;
5102290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    }
5112290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
512d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn    public static <T> boolean equalsSetHelper(Set<T> set, Object object) {
513d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        if (set == object) {
514d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            return true;
515d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        }
516d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        if (object instanceof Set) {
517d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            Set<?> s = (Set<?>) object;
518d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn
519d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            try {
520d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                return set.size() == s.size() && set.containsAll(s);
521d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            } catch (NullPointerException ignored) {
522d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                return false;
523d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            } catch (ClassCastException ignored) {
524d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                return false;
525d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            }
526d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        }
527d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        return false;
528d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn    }
529d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn
5302290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    public Set<Map.Entry<K, V>> getEntrySet() {
5312290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        if (mEntrySet == null) {
5322290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mEntrySet = new EntrySet();
5332290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
5342290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        return mEntrySet;
5352290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    }
5362290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
5372290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    public Set<K> getKeySet() {
5382290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        if (mKeySet == null) {
5392290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mKeySet = new KeySet();
5402290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
5412290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        return mKeySet;
5422290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    }
5432290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
5442290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    public Collection<V> getValues() {
5452290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        if (mValues == null) {
5462290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mValues = new ValuesCollection();
5472290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
5482290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        return mValues;
5492290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    }
5502290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
5512290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    protected abstract int colGetSize();
5522290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    protected abstract Object colGetEntry(int index, int offset);
5532290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    protected abstract int colIndexOfKey(Object key);
5542290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    protected abstract int colIndexOfValue(Object key);
5552290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    protected abstract Map<K, V> colGetMap();
5562290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    protected abstract void colPut(K key, V value);
5572290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    protected abstract V colSetValue(int index, V value);
5582290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    protected abstract void colRemoveAt(int index);
5592290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    protected abstract void colClear();
5602290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn}
561