⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstracthashedmap.java

📁 jboss规则引擎
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
                return oldValue;
            }
            previous = entry;
            entry = entry.next;
        }
        return null;
    }

    /**
     * Clears the map, resetting the size to zero and nullifying references to
     * avoid garbage collection issues.
     */
    public void clear() {
        this.modCount++;
        final HashEntry[] data = this.data;
        for ( int i = data.length - 1; i >= 0; i-- ) {
            data[i] = null;
        }
        this.size = 0;
    }

    // -----------------------------------------------------------------------
    /**
     * Converts input keys to another object for storage in the map. This
     * implementation masks nulls. Subclasses can override this to perform
     * alternate key conversions.
     * <p>
     * The reverse conversion can be changed, if required, by overriding the
     * getKey() method in the hash entry.
     * 
     * @param key
     *            the key convert
     * @return the converted key
     */
    protected Object convertKey(final Object key) {
        return (key == null ? AbstractHashedMap.NULL : key);
    }

    /**
     * Gets the hash code for the key specified. This implementation uses the
     * additional hashing routine from JDK1.4. Subclasses can override this to
     * return alternate hash codes.
     * 
     * @param key
     *            the key to get a hash code for
     * @return the hash code
     */
    protected int hash(final Object key) {
        // same as JDK 1.4
        int h = key.hashCode();
        h += ~(h << 9);
        h ^= (h >>> 14);
        h += (h << 4);
        h ^= (h >>> 10);
        return h;
    }

    /**
     * Compares two keys, in internal converted form, to see if they are equal.
     * This implementation uses the equals method and assumes neither key is
     * null. Subclasses can override this to match differently.
     * 
     * @param key1
     *            the first key to compare passed in from outside
     * @param key2
     *            the second key extracted from the entry via
     *            <code>entry.key</code>
     * @return true if equal
     */
    protected boolean isEqualKey(final Object key1,
                                 final Object key2) {
        return (key1 == key2 || key1.equals( key2 ));
    }

    /**
     * Compares two values, in external form, to see if they are equal. This
     * implementation uses the equals method and assumes neither value is null.
     * Subclasses can override this to match differently.
     * 
     * @param value1
     *            the first value to compare passed in from outside
     * @param value2
     *            the second value extracted from the entry via
     *            <code>getValue()</code>
     * @return true if equal
     */
    protected boolean isEqualValue(final Object value1,
                                   final Object value2) {
        return (value1 == value2 || value1.equals( value2 ));
    }

    /**
     * Gets the index into the data storage for the hashCode specified. This
     * implementation uses the least significant bits of the hashCode.
     * Subclasses can override this to return alternate bucketing.
     * 
     * @param hashCode
     *            the hash code to use
     * @param dataSize
     *            the size of the data to pick a bucket from
     * @return the bucket index
     */
    protected int hashIndex(final int hashCode,
                            final int dataSize) {
        return hashCode & (dataSize - 1);
    }

    // -----------------------------------------------------------------------
    /**
     * Gets the entry mapped to the key specified.
     * <p>
     * This method exists for subclasses that may need to perform a multi-step
     * process accessing the entry. The public methods in this class don't use
     * this method to gain a small performance boost.
     * 
     * @param key
     *            the key
     * @return the entry, null if no match
     */
    protected HashEntry getEntry(Object key) {
        key = convertKey( key );
        final int hashCode = hash( key );
        HashEntry entry = this.data[hashIndex( hashCode,
                                               this.data.length )]; // no local
        // for hash
        // index
        while ( entry != null ) {
            if ( entry.hashCode == hashCode && isEqualKey( key,
                                                           entry.key ) ) {
                return entry;
            }
            entry = entry.next;
        }
        return null;
    }

    // -----------------------------------------------------------------------
    /**
     * Updates an existing key-value mapping to change the value.
     * <p>
     * This implementation calls <code>setValue()</code> on the entry.
     * Subclasses could override to handle changes to the map.
     * 
     * @param entry
     *            the entry to update
     * @param newValue
     *            the new value to store
     */
    protected void updateEntry(final HashEntry entry,
                               final Object newValue) {
        entry.setValue( newValue );
    }

    /**
     * Reuses an existing key-value mapping, storing completely new data.
     * <p>
     * This implementation sets all the data fields on the entry. Subclasses
     * could populate additional entry fields.
     * 
     * @param entry
     *            the entry to update, not null
     * @param hashIndex
     *            the index in the data array
     * @param hashCode
     *            the hash code of the key to add
     * @param key
     *            the key to add
     * @param value
     *            the value to add
     */
    protected void reuseEntry(final HashEntry entry,
                              final int hashIndex,
                              final int hashCode,
                              final Object key,
                              final Object value) {
        entry.next = this.data[hashIndex];
        entry.hashCode = hashCode;
        entry.key = key;
        entry.value = value;
    }

    // -----------------------------------------------------------------------
    /**
     * Adds a new key-value mapping into this map.
     * <p>
     * This implementation calls <code>createEntry()</code>,
     * <code>addEntry()</code> and <code>checkCapacity()</code>. It also
     * handles changes to <code>modCount</code> and <code>size</code>.
     * Subclasses could override to fully control adds to the map.
     * 
     * @param hashIndex
     *            the index into the data array to store at
     * @param hashCode
     *            the hash code of the key to add
     * @param key
     *            the key to add
     * @param value
     *            the value to add
     */
    protected void addMapping(final int hashIndex,
                              final int hashCode,
                              final Object key,
                              final Object value) {
        this.modCount++;
        final HashEntry entry = createEntry( this.data[hashIndex],
                                             hashCode,
                                             key,
                                             value );
        addEntry( entry,
                  hashIndex );
        this.size++;
        checkCapacity();
    }

    /**
     * Creates an entry to store the key-value data.
     * <p>
     * This implementation creates a new HashEntry instance. Subclasses can
     * override this to return a different storage class, or implement caching.
     * 
     * @param next
     *            the next entry in sequence
     * @param hashCode
     *            the hash code to use
     * @param key
     *            the key to store
     * @param value
     *            the value to store
     * @return the newly created entry
     */
    protected HashEntry createEntry(final HashEntry next,
                                    final int hashCode,
                                    final Object key,
                                    final Object value) {
        return new HashEntry( next,
                              hashCode,
                              key,
                              value );
    }

    /**
     * Adds an entry into this map.
     * <p>
     * This implementation adds the entry to the data storage table. Subclasses
     * could override to handle changes to the map.
     * 
     * @param entry
     *            the entry to add
     * @param hashIndex
     *            the index into the data array to store at
     */
    protected void addEntry(final HashEntry entry,
                            final int hashIndex) {
        this.data[hashIndex] = entry;
    }

    // -----------------------------------------------------------------------
    /**
     * Removes a mapping from the map.
     * <p>
     * This implementation calls <code>removeEntry()</code> and
     * <code>destroyEntry()</code>. It also handles changes to
     * <code>modCount</code> and <code>size</code>. Subclasses could
     * override to fully control removals from the map.
     * 
     * @param entry
     *            the entry to remove
     * @param hashIndex
     *            the index into the data structure
     * @param previous
     *            the previous entry in the chain
     */
    protected void removeMapping(final HashEntry entry,
                                 final int hashIndex,
                                 final HashEntry previous) {
        this.modCount++;
        removeEntry( entry,
                     hashIndex,
                     previous );
        this.size--;
        destroyEntry( entry );
    }

    /**
     * Removes an entry from the chain stored in a particular index.
     * <p>
     * This implementation removes the entry from the data storage table. The
     * size is not updated. Subclasses could override to handle changes to the
     * map.
     * 
     * @param entry
     *            the entry to remove
     * @param hashIndex
     *            the index into the data structure
     * @param previous
     *            the previous entry in the chain
     */
    protected void removeEntry(final HashEntry entry,
                               final int hashIndex,
                               final HashEntry previous) {
        if ( previous == null ) {
            this.data[hashIndex] = entry.next;
        } else {
            previous.next = entry.next;
        }
    }

    /**
     * Kills an entry ready for the garbage collector.
     * <p>
     * This implementation prepares the HashEntry for garbage collection.
     * Subclasses can override this to implement caching (override clear as
     * well).
     * 
     * @param entry
     *            the entry to destroy
     */
    protected void destroyEntry(final HashEntry entry) {
        entry.next = null;
        entry.key = null;
        entry.value = null;
    }

    // -----------------------------------------------------------------------
    /**
     * Checks the capacity of the map and enlarges it if necessary.
     * <p>
     * This implementation uses the threshold to check if the map needs
     * enlarging
     */
    protected void checkCapacity() {
        if ( this.size >= this.threshold ) {
            final int newCapacity = this.data.length * 2;
            if ( newCapacity <= AbstractHashedMap.MAXIMUM_CAPACITY ) {
                ensureCapacity( newCapacity );
            }
        }
    }

    /**
     * Changes the size of the data structure to the capacity proposed.
     * 
     * @param newCapacity
     *            the new capacity of the array (a power of two, less or equal
     *            to max)
     */
    protected void ensureCapacity(final int newCapacity) {
        final int oldCapacity = this.data.length;
        if ( newCapacity <= oldCapacity ) {
            return;
        }
        if ( this.size == 0 ) {
            this.threshold = calculateThreshold( newCapacity,
                                                 this.loadFactor );
            this.data = new HashEntry[newCapacity];
        } else {
            final HashEntry oldEntries[] = this.data;
            final HashEntry newEntries[] = new HashEntry[newCapacity];

            this.modCount++;
            for ( int i = oldCapacity - 1; i >= 0; i-- ) {
                HashEntry entry = oldEntries[i];
                if ( entry != null ) {
                    oldEntries[i] = null; // gc
                    do {
                        final HashEntry next = entry.next;
                        final int index = hashIndex( entry.hashCode,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -