JDK源码分析——性能优化实例

1、 尽可能的用位运算 ,比如HashMap的查找Entry<K, V> [] table下标的操作
static   int  indexFor( int  h,  int  length) {
    
return  h  &  (length - 1 );
}

2、 对于java.utl.ArrayList、HashMap、LinkedHashMap、HashSet、LinkedSet等的new操作最好指定所需大小。
    2.1、对于ArrayList来说add操作有一行代码为:ensureCapacity(size + 1);具体实现如下:
 1  public   void  ensureCapacity( int  minCapacity) {
 2      modCount ++ ;
 3       int  oldCapacity  =  elementData.length;
 4       if  (minCapacity  >  oldCapacity) {
 5          Object oldData[]  =  elementData;
 6           int  newCapacity  =  (oldCapacity  *   3 ) / 2   +   1 ;
 7               if  (newCapacity  <  minCapacity)
 8          newCapacity  =  minCapacity;
 9               //  minCapacity is usually close to size, so this is a win:
10              elementData  =  Arrays.copyOf(elementData, newCapacity);
11      }
12  }
    可以看出,如果ArrayList超出原先的容量,需要扩容的时候,是先new一个数组,然后把原来的数组拷贝到新数组中。所以如果原先可以确定容量的话,采用public ArrayList(int initialCapacity)构造方法。

    2.2、对于HashMap来说put操作,如果在原有的key中没有找到匹配项,则需要把key加入到Entry<>[] table中。        具体代码如下:
1  void  addEntry( int  hash, K key, V value,  int  bucketIndex) {
2      Entry < K,V >  e  =  table[bucketIndex];
3      table[bucketIndex]  =   new  Entry < K,V > (hash, key, value, e);
4       if  (size ++   >=  threshold)
5           //  当size++ >= 负载因子时,进行扩容操作
6          resize( 2   *  table.length);
7  }
  resize(int newCapacity)代码如下:
 1  void  resize( int  newCapacity) {
 2      Entry[] oldTable  =  table;
 3       int  oldCapacity  =  oldTable.length;
 4       if  (oldCapacity  ==  MAXIMUM_CAPACITY) {
 5          threshold  =  Integer.MAX_VALUE;
 6           return ;
 7      }
 8       //  需要重新new 一个Entry数组
 9      Entry[] newTable  =   new  Entry[newCapacity];
10      transfer(newTable);
11      table  =  newTable;
12      threshold  =  ( int )(newCapacity  *  loadFactor);
13  }
这里调用一个方法transfer(Entry[] newTable)其代码如下:
 1  void  transfer(Entry[] newTable) {
 2      Entry[] src  =  table;
 3       int  newCapacity  =  newTable.length;
 4       //  对Entry[] src进行循环,把旧的Entry[]拷贝到新的Entry[]中
 5       for  ( int  j  =   0 ; j  <  src.length; j ++ ) {
 6          Entry < K,V >  e  =  src[j];
 7           if  (e  !=   null ) {
 8               //  把src赋值为null,为了GC操作的时候,回收原来的Entry[]
 9              src[j]  =   null ;
10               //  对table[j]的链表进行循环
11               do  {
12                  Entry < K,V >  next  =  e.next;
13                   //  计算在新的Entry[]数组的下标
14                   int  i  =  indexFor(e.hash, newCapacity);
15                  
16                  e.next  =  newTable[i];
17                  newTable[i]  =  e;
18                  e  =  next;
19              }  while  (e  !=   null );
20          }
21      }
22  }
    2.3、HashSet、LinkedSet、LinkedMap与上同

3、 数组复制的时候,用System.arraycopy方法 ,比如2.1中的ensureCapacity(int minCapacity)方法,调用的Arrays.copyOf方法。在Array.copy中调用了System.arraycopy,其代码如下:
1  public   static   < T,U >  T[] copyOf(U[] original,  int  newLength, Class <?   extends  T[] >  newType) {
2      T[] copy  =  ((Object)newType  ==  (Object)Object[]. class )
3           ?  (T[])  new  Object[newLength]
4          : (T[]) Array.newInstance(newType.getComponentType(), newLength);
5      System.arraycopy(original,  0 , copy,  0 ,
6                       Math.min(original.length, newLength));
7       return  copy;
8  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值