package toxi.util.datatypes; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; /** * This class is used to build an unique set of items and offers a * bi-directional mapping between items and their associated ID values. Items * are added via the {@link #index(Object)} method and removed via * {@link #unindex(Object)}. The item's {@link #hashCode()} is used as unique * identifier, so you MUST ensure the item class satisfies the contract of * {@link #hashCode()} and {@link #equals(Object)}. * @param <T> */ public class UniqueItemIndex<T> implements ItemIndex<T> { /** * */ protected final HashMap<T, Integer> uniqueItems = new HashMap<>(); /** * */ protected final ArrayList<T> index = new ArrayList<>(); /** * */ public UniqueItemIndex() { } /** * * @param items */ public UniqueItemIndex(Collection<T> items) { for (T item : items) { index(item); } } /* * (non-Javadoc) * * @see toxi.util.ItemIndex#clear() */ /** * */ @Override public void clear() { uniqueItems.clear(); index.clear(); } /* * (non-Javadoc) * * @see toxi.util.ItemIndex#forID(int) */ /** * * @param id * @return */ @Override public T forID(int id) { return index.get(id); } /* * (non-Javadoc) * * @see toxi.util.ItemIndex#getID(T) */ /** * * @param item * @return */ @Override public int getID(T item) { Integer id = uniqueItems.get(item); return (id != null) ? id : -1; } /* * (non-Javadoc) * * @see toxi.util.ItemIndex#getItems() */ /** * * @return */ @Override public List<T> getItems() { return index; } /* * (non-Javadoc) * * @see toxi.util.ItemIndex#index(T) */ /** * * @param item * @return */ @Override public int index(T item) { Integer id = uniqueItems.get(item); if (id == null) { id = index.size(); uniqueItems.put(item, id); index.add(item); } return id; } /* * (non-Javadoc) * * @see toxi.util.ItemIndex#isIndexed(T) */ /** * * @param item * @return */ @Override public boolean isIndexed(T item) { return uniqueItems.get(item) != null; } /* * (non-Javadoc) * * @see toxi.util.ItemIndex#reindex(T, T) */ /** * * @param item * @param newItem * @return */ @Override public int reindex(T item, T newItem) { int id = getID(item); if (id != -1) { int newID = getID(newItem); if (newID != -1) { unindex(item); id = getID(newItem); } else { index.set(id, newItem); uniqueItems.remove(item); uniqueItems.put(newItem, id); } } return id; } /* * (non-Javadoc) * * @see toxi.util.ItemIndex#size() */ /** * * @return */ @Override public int size() { return index.size(); } /* * (non-Javadoc) * * @see toxi.util.ItemIndex#unindex(T) */ /** * * @param item * @return */ @Override public int unindex(T item) { Integer id = uniqueItems.get(item); if (id != null) { uniqueItems.remove(item); index.remove(item); for (int i = id, num = index.size(); i < num; i++) { uniqueItems.put(index.get(i), i); } } else { id = -1; } return id; } }