首页

分享hessian的IdentityIntMap通过数组KV实现简单HashMap的源码

标签:hessian,自定义Map,IdentityIntMap,map实现原理     发布时间:2018-02-06   

一、前言

这边基于hessian的com.caucho.hessian.util.IdentityIntMap实现简单的HashMap-从对象Key到整型int简单转换,并实现HashMap的基本API,具体参见如下代码说明

二、源码说明

package com.caucho.hessian.util;@b@@b@/**@b@ * The IntMap provides a simple hashmap from keys to integers.  The API is@b@ * an abbreviation of the HashMap collection API.@b@ *@b@ * <p>The convenience of IntMap is avoiding all the silly wrapping of@b@ * integers.@b@ */@b@public class IdentityIntMap {@b@  /**@b@   * Encoding of a null entry.  Since NULL is equal to Integer.MIN_VALUE,@b@   * it's impossible to distinguish between the two.@b@   */@b@  public final static int NULL = 0xdeadbeef; // Integer.MIN_VALUE + 1;@b@@b@  private Object []_keys;@b@  private int []_values;@b@@b@  private int _size;@b@  private int _prime;@b@@b@  /**@b@   * Create a new IntMap.  Default size is 16.@b@   */@b@  public IdentityIntMap(int capacity)@b@  {@b@    _keys = new Object[capacity];@b@    _values = new int[capacity];@b@@b@    _prime = getBiggestPrime(_keys.length);@b@    _size = 0;@b@  }@b@@b@  /**@b@   * Clear the hashmap.@b@   */@b@  public void clear()@b@  {@b@    final Object []keys = _keys;@b@    final int []values = _values;@b@@b@    for (int i = keys.length - 1; i >= 0; i--) {@b@      keys[i] = null;@b@      values[i] = 0;@b@    }@b@@b@    _size = 0;@b@  }@b@  /**@b@   * Returns the current number of entries in the map.@b@   */@b@  public final int size()@b@  {@b@    return _size;@b@  }@b@@b@  /**@b@   * Puts a new value in the property table with the appropriate flags@b@   */@b@  public final int get(Object key)@b@  {@b@    int prime = _prime;@b@    int hash = System.identityHashCode(key) % prime;@b@    // int hash = key.hashCode() & mask;@b@@b@    final Object []keys = _keys;@b@@b@    while (true) {@b@      Object mapKey = keys[hash];@b@@b@      if (mapKey == null)@b@        return NULL;@b@      else if (mapKey == key)@b@        return _values[hash];@b@@b@      hash = (hash + 1) % prime;@b@    }@b@  }@b@@b@  /**@b@   * Puts a new value in the property table with the appropriate flags@b@   */@b@  public final int put(Object key, int value, boolean isReplace)@b@  {@b@    int prime = _prime;@b@    int hash = Math.abs(System.identityHashCode(key) % prime);@b@    // int hash = key.hashCode() % prime;@b@@b@    Object []keys = _keys;@b@@b@    while (true) {@b@      Object testKey = keys[hash];@b@@b@      if (testKey == null) {@b@        keys[hash] = key;@b@        _values[hash] = value;@b@@b@        _size++;@b@@b@        if (keys.length <= 4 * _size)@b@          resize(4 * keys.length);@b@@b@        return value;@b@      }@b@      else if (key != testKey) {@b@        hash = (hash + 1) % prime;@b@@b@        continue;@b@      }@b@      else if (isReplace){@b@        int old = _values[hash];@b@@b@        _values[hash] = value;@b@@b@        return old;@b@      }@b@      else {@b@        return _values[hash];@b@      }@b@    }@b@  }@b@@b@  /**@b@   * Removes a value in the property table.@b@   */@b@  public final void remove(Object key)@b@  {@b@    if (put(key, NULL, true) != NULL) {@b@      _size--;@b@    }@b@  }@b@@b@  /**@b@   * Expands the property table@b@   */@b@  private void resize(int newSize)@b@  {@b@    Object []keys = _keys;@b@    int values[] = _values;@b@@b@    _keys = new Object[newSize];@b@    _values = new int[newSize];@b@    _size = 0;@b@@b@    _prime = getBiggestPrime(_keys.length);@b@@b@    for (int i = keys.length - 1; i >= 0; i--) {@b@      Object key = keys[i];@b@      int value = values[i];@b@@b@      if (key != null && value != NULL) {@b@        put(key, value, true);@b@      }@b@    }@b@  }@b@@b@  protected int hashCode(Object value)@b@  {@b@    return System.identityHashCode(value);@b@  }@b@@b@  public String toString()@b@  {@b@    StringBuffer sbuf = new StringBuffer();@b@@b@    sbuf.append("IntMap[");@b@    boolean isFirst = true;@b@@b@    for (int i = 0; i <= _keys.length; i++) {@b@      if (_keys[i] != null) {@b@        if (! isFirst)@b@          sbuf.append(", ");@b@@b@        isFirst = false;@b@        sbuf.append(_keys[i]);@b@        sbuf.append(":");@b@        sbuf.append(_values[i]);@b@      }@b@    }@b@    sbuf.append("]");@b@@b@    return sbuf.toString();@b@  }@b@@b@  public static final int []PRIMES =@b@  {@b@   1,       /* 1<< 0 = 1 */@b@   2,       /* 1<< 1 = 2 */@b@   3,       /* 1<< 2 = 4 */@b@   7,       /* 1<< 3 = 8 */@b@   13,      /* 1<< 4 = 16 */@b@   31,      /* 1<< 5 = 32 */@b@   61,      /* 1<< 6 = 64 */@b@   127,     /* 1<< 7 = 128 */@b@   251,     /* 1<< 8 = 256 */@b@   509,     /* 1<< 9 = 512 */@b@   1021,    /* 1<<10 = 1024 */@b@   2039,    /* 1<<11 = 2048 */@b@   4093,    /* 1<<12 = 4096 */@b@   8191,    /* 1<<13 = 8192 */@b@   16381,   /* 1<<14 = 16384 */@b@   32749,   /* 1<<15 = 32768 */@b@   65521,   /* 1<<16 = 65536 */@b@   131071,  /* 1<<17 = 131072 */@b@   262139,  /* 1<<18 = 262144 */@b@   524287,  /* 1<<19 = 524288 */@b@   1048573, /* 1<<20 = 1048576 */@b@   2097143, /* 1<<21 = 2097152 */@b@   4194301, /* 1<<22 = 4194304 */@b@   8388593, /* 1<<23 = 8388608 */@b@   16777213, /* 1<<24 = 16777216 */@b@   33554393, /* 1<<25 = 33554432 */@b@   67108859, /* 1<<26 = 67108864 */@b@   134217689, /* 1<<27 = 134217728 */@b@   268435399, /* 1<<28 = 268435456 */@b@  };@b@@b@  public static int getBiggestPrime(int value)@b@  {@b@    for (int i = PRIMES.length - 1; i >= 0; i--) {@b@      if (PRIMES[i] <= value)@b@        return PRIMES[i];@b@    }@b@@b@    return 2;@b@  }@b@}