/******************************************************************************* * Copyright 2011 See AUTHORS file. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package com.badlogic.gdx.utils; import java.util.NoSuchElementException; import chbachman.api.util.Array; /** * An {@link ObjectSet} that also stores keys in an {@link Array} using the * insertion order. There is some additional overhead for put and remove. * {@link #iterator() Iteration} is ordered and faster than an unordered set. * Keys can also be accessed and the order changed using {@link #orderedItems()} * . * * @author Nathan Sweet */ public class OrderedSet<T> extends ObjectSet<T> { final Array<T> items; OrderedSetIterator iterator1, iterator2; public OrderedSet() { items = new Array(); } public OrderedSet(int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor); items = new Array(capacity); } public OrderedSet(int initialCapacity) { super(initialCapacity); items = new Array(capacity); } public OrderedSet(OrderedSet set) { super(set); items = new Array(capacity); items.addAll(set.items); } public boolean add(T key) { if (!contains(key)) items.add(key); return super.add(key); } public boolean remove(T key) { items.removeValue(key, false); return super.remove(key); } public void clear(int maximumCapacity) { items.clear(); super.clear(maximumCapacity); } public void clear() { items.clear(); super.clear(); } public Array<T> orderedItems() { return items; } public OrderedSetIterator<T> iterator() { if (iterator1 == null) { iterator1 = new OrderedSetIterator(this); iterator2 = new OrderedSetIterator(this); } if (!iterator1.valid) { iterator1.reset(); iterator1.valid = true; iterator2.valid = false; return iterator1; } iterator2.reset(); iterator2.valid = true; iterator1.valid = false; return iterator2; } public String toString() { if (size == 0) return "{}"; StringBuilder buffer = new StringBuilder(32); buffer.append('{'); Array<T> keys = this.items; for (int i = 0, n = keys.size; i < n; i++) { T key = keys.get(i); if (i > 0) buffer.append(", "); buffer.append(key); } buffer.append('}'); return buffer.toString(); } static public class OrderedSetIterator<T> extends ObjectSetIterator<T> { private Array<T> items; public OrderedSetIterator(OrderedSet<T> set) { super(set); items = set.items; } public void reset() { nextIndex = 0; hasNext = set.size > 0; } public T next() { if (!hasNext) throw new NoSuchElementException(); if (!valid) throw new GdxRuntimeException("#iterator() cannot be used nested."); T key = items.get(nextIndex); nextIndex++; hasNext = nextIndex < set.size; return key; } public void remove() { if (nextIndex < 0) throw new IllegalStateException("next must be called before remove."); nextIndex--; set.remove(items.get(nextIndex)); } } }