001: /*
002: [The "BSD licence"]
003: Copyright (c) 2005-2006 Terence Parr
004: All rights reserved.
005:
006: Redistribution and use in source and binary forms, with or without
007: modification, are permitted provided that the following conditions
008: are met:
009: 1. Redistributions of source code must retain the above copyright
010: notice, this list of conditions and the following disclaimer.
011: 2. Redistributions in binary form must reproduce the above copyright
012: notice, this list of conditions and the following disclaimer in the
013: documentation and/or other materials provided with the distribution.
014: 3. The name of the author may not be used to endorse or promote products
015: derived from this software without specific prior written permission.
016:
017: THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
018: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
019: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
020: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
021: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
022: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
023: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
024: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
026: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027: */
028: package org.antlr.misc;
029:
030: import org.antlr.tool.ErrorManager;
031:
032: import java.util.*;
033:
034: /** A HashMap that remembers the order that the elements were added.
035: * You can alter the ith element with set(i,value) too :) Unique list.
036: * I need the replace/set-element-i functionality so I'm subclassing
037: * OrderedHashSet.
038: */
039: public class OrderedHashSet extends HashSet {
040: /** Track the elements as they are added to the set */
041: protected List elements = new ArrayList();
042:
043: public Object get(int i) {
044: return elements.get(i);
045: }
046:
047: /** Replace an existing value with a new value; updates the element
048: * list and the hash table, but not the key as that has not changed.
049: */
050: public Object set(int i, Object value) {
051: Object oldElement = elements.get(i);
052: elements.set(i, value); // update list
053: super .remove(oldElement); // now update the set: remove/add
054: super .add(value);
055: return oldElement;
056: }
057:
058: /** Add a value to list; keep in hashtable for consistency also;
059: * Key is object itself. Good for say asking if a certain string is in
060: * a list of strings.
061: */
062: public boolean add(Object value) {
063: boolean result = super .add(value);
064: if (result) { // only track if new element not in set
065: elements.add(value);
066: }
067: return result;
068: }
069:
070: public boolean remove(Object o) {
071: throw new UnsupportedOperationException();
072: /*
073: elements.remove(o);
074: return super.remove(o);
075: */
076: }
077:
078: public void clear() {
079: elements.clear();
080: super .clear();
081: }
082:
083: /** Return the List holding list of table elements. Note that you are
084: * NOT getting a copy so don't write to the list.
085: */
086: public List elements() {
087: return elements;
088: }
089:
090: public int size() {
091: if (elements.size() != super .size()) {
092: ErrorManager
093: .internalError("OrderedHashSet: elements and set size differs; "
094: + elements.size() + "!=" + super .size());
095: }
096: return elements.size();
097: }
098:
099: public String toString() {
100: return elements.toString();
101: }
102: }
|