Samwey—–优雅设计------HashMap

针对ES5不支持对象为key设计的一个HashMap
Map 接口

interface JTIMap<K extends any, V extends any> extends JTIPoolObject
{
/**
* 获取所有的子元素列表。
*/
values:V[]

/**
 * 获取所有的子元素键名列表。
 */
keys:K[]

/**总个数 */
size:number

/**
 * 给指定的键名设置值。
 * @param   key 键名。
 * @param   value 值。
 */
set(key:K, value:V):void

/**
 * 是否包含指定Key
 * @param key 键名对象。
 * @returns 是否包含
 */
containsKey(key:K):boolean

/**
 * 返回指定键名的值。
 * @param   key 键名对象。
 * @return 指定键名的值。
 */
get(key:K):V

/**
 * 移除指定键名的值。
 * @param   key 键名对象。
 * @return 返回移除对象。
 */
remove(key:K):V

/**
 * 移除Map中的值
 * @param value 以值来移除Map中的值
 * @returns 返回移除键。
 */
removeValue(value:V):K

/**
 * 清除此对象的键名列表和键值列表。
 */
clear():void

HashMap具体实现

class JTHashMap<K, V> implements JTIMap<K , V>
{

private _keys:K[] = null;
private _valueMap:{[key:number]:V} = null;
private _emptys:JTStack<number> = null;
private _size:number = 0;
private _hashCode:number = 0;
public constructor()
{
    this._keys = [];
    this._emptys = new JTStack();
    this._valueMap = Object.create(null);
}



/**

 * 给指定的键名设置值。
 * @param   key 键名。
 * @param   value 值。
 */

public set(key:K, value:V):void
{
    let hashCode:number = this.getHashCode(key);
    if (hashCode > -1){   this._valueMap[hashCode] = value; return};
    if (this._emptys.size < 1)hashCode = this._hashCode ++;
    else  hashCode = this._emptys.deQueue();
    this._keys[hashCode] = key;
    this._valueMap[hashCode] = value;
    this._size ++;
}



/**
 * 获取指定对象的键名索引。
 * @param   key 键名对象。
 * @return 键名索引(hash值)。
 */
private getHashCode(key:K):number
{
    return !key ? -1 :this._keys.indexOf(key);
}

/**
 * 是否包含指定Key
 * @param key 键名对象。
 * @returns 是否包含
 */

public containsKey(key:K):boolean
{
    return this.getHashCode(key) > -1;
}



/**
 * 返回指定键名的值。
 * @param   key 键名对象。
 * @return 指定键名的值。
 */

public get(key:K):V
{
    var hashCode:number = this.getHashCode(key);
   return hashCode == -1 ? null : this._valueMap[hashCode];
}

/**
 * 通过HashCode获取值
 * @param hashCode
 * @returns
 */
public getValue(hashCode:number):V
{
   return this._valueMap[hashCode];
}

/**
 *
 * @param hashCode
 * @returns
 */
public containsValue(hashCode:number):boolean
{
    return hashCode in this._valueMap;
}



/**
 * 移除指定键名的值。
 * @param   key 键名对象。
 * @return 返回移除对象。
 */
public remove(key:K):V
{
    var hashCode:number = this.getHashCode(key);
    if (hashCode > -1)
    {
        let value:V = this._valueMap[hashCode];
        delete this._valueMap[hashCode]
        this.del(hashCode)
        return value;
    }
    return null;
}

/**
 * 移除Map中的值
 * @param value 以值来移除Map中的值
 * @returns 返回移除键。
 */

public removeValue(value:V):K
{

    let oldVal:V = null;
    let _valueMap:JTHashMap<K,V> = this._valueMap as any;
    for (let key in _valueMap)
    {
        oldVal = _valueMap[key];
        if (oldVal != value) continue;
        delete _valueMap[key];
        let hashCode:number = parseInt(key);
        let oldKey:K = this._keys[hashCode];
        this.del(hashCode)
        return oldKey;
    }
    return null;
}

private del(index:number):void
{
    this._size --;
    this._keys[index] = null;
    this._emptys.enQueue(index);
}

/**
 * 获取所有的子元素列表。
 */
public get values():V[]
{
    let _values:V[] = [];
    let keys:K[] = this._keys;
    let l:number = keys.length;
    let _valueMap:{[key:number]:V} = this._valueMap;
    for (let i:number = 0; i < l; i++)
    {
        _valueMap[i] && _values.push(_valueMap[i])
    }
    return _values;
}

   

/**
 * 获取所有的子元素键名列表。
 */
public get keys():K[]
{
    return [].concat(this._keys);
}

public get size():number
{
    return this._size;
}



/**
 * 清除此对象的键名列表和键值列表。
 */

public clear():void
{
    if (this._size > 0)this._valueMap = Object.create(null);
    this._size = this._keys.length = this._hashCode = 0;
    this._emptys.clear();
}

public recycle(): void
{
    this.clear();
}

}

非常优雅,跟我的名字一样优雅 :laughing:

:rofl::rofl::rofl::rofl::rofl:

weakMap?

恩恩。支持键为对象的存取的。