170 lines
4.3 KiB
Java
170 lines
4.3 KiB
Java
/*******************************************************************************
|
|
* Copyright 2011 LibGDX.
|
|
* Mario Zechner <badlogicgames@gmail.com>
|
|
* Nathan Sweet <nathan.sweet@gmail.com>
|
|
*
|
|
* 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 dorkbox.collections;
|
|
|
|
import java.util.NoSuchElementException;
|
|
|
|
/** An {@link ObjectSet} that also stores keys in an {@link Array} using the insertion order. {@link #iterator() Iteration} is
|
|
* ordered and faster than an unordered set. Keys can also be accessed and the order changed using {@link #orderedItems()}. There
|
|
* is some additional overhead for put and remove. When used for faster iteration versus ObjectSet and the order does not actually
|
|
* matter, copying during remove can be greatly reduced by setting {@link Array#ordered} to false for
|
|
* {@link OrderedSet#orderedItems()}.
|
|
* @author Nathan Sweet */
|
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
|
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);
|
|
}
|
|
|
|
@Override
|
|
public boolean add (T key) {
|
|
if (!super.add(key)) return false;
|
|
items.add(key);
|
|
return true;
|
|
}
|
|
|
|
public boolean add (T key, int index) {
|
|
if (!super.add(key)) {
|
|
items.removeValue(key, true);
|
|
items.insert(index, key);
|
|
return false;
|
|
}
|
|
items.insert(index, key);
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean remove (T key) {
|
|
if (!super.remove(key)) return false;
|
|
items.removeValue(key, false);
|
|
return true;
|
|
}
|
|
|
|
public T removeIndex (int index) {
|
|
T key = items.removeIndex(index);
|
|
super.remove(key);
|
|
return key;
|
|
}
|
|
|
|
@Override
|
|
public void clear (int maximumCapacity) {
|
|
items.clear();
|
|
super.clear(maximumCapacity);
|
|
}
|
|
|
|
@Override
|
|
public void clear () {
|
|
items.clear();
|
|
super.clear();
|
|
}
|
|
|
|
public Array<T> orderedItems () {
|
|
return items;
|
|
}
|
|
|
|
@Override
|
|
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;
|
|
}
|
|
|
|
@Override
|
|
public String toString () {
|
|
if (size == 0) return "{}";
|
|
T[] items = this.items.items;
|
|
StringBuilder buffer = new StringBuilder(32);
|
|
buffer.append('{');
|
|
buffer.append(items[0]);
|
|
for (int i = 1; i < size; i++) {
|
|
buffer.append(", ");
|
|
buffer.append(items[i]);
|
|
}
|
|
buffer.append('}');
|
|
return buffer.toString();
|
|
}
|
|
|
|
@Override
|
|
public String toString (String separator) {
|
|
return items.toString(separator);
|
|
}
|
|
|
|
static public class OrderedSetIterator<T> extends ObjectSetIterator<T> {
|
|
private Array<T> items;
|
|
|
|
public OrderedSetIterator (OrderedSet<T> set) {
|
|
super(set);
|
|
items = set.items;
|
|
}
|
|
|
|
@Override
|
|
public void reset () {
|
|
nextIndex = 0;
|
|
hasNext = set.size > 0;
|
|
}
|
|
|
|
@Override
|
|
public T next () {
|
|
if (!hasNext) throw new NoSuchElementException();
|
|
if (!valid) throw new RuntimeException("#iterator() cannot be used nested.");
|
|
T key = items.get(nextIndex);
|
|
nextIndex++;
|
|
hasNext = nextIndex < set.size;
|
|
return key;
|
|
}
|
|
|
|
@Override
|
|
public void remove () {
|
|
if (nextIndex < 0) throw new IllegalStateException("next must be called before remove.");
|
|
nextIndex--;
|
|
((OrderedSet)set).removeIndex(nextIndex);
|
|
}
|
|
}
|
|
}
|