1、
尽可能的用位运算
,比如HashMap的查找Entry<K, V> [] table下标的操作
2、 对于java.utl.ArrayList、HashMap、LinkedHashMap、HashSet、LinkedSet等的new操作最好指定所需大小。
2.1、对于ArrayList来说add操作有一行代码为:ensureCapacity(size + 1);具体实现如下:
2.2、对于HashMap来说put操作,如果在原有的key中没有找到匹配项,则需要把key加入到Entry<>[] table中。 具体代码如下:
3、 数组复制的时候,用System.arraycopy方法 ,比如2.1中的ensureCapacity(int minCapacity)方法,调用的Arrays.copyOf方法。在Array.copy中调用了System.arraycopy,其代码如下:
static
int
indexFor(
int
h,
int
length) {
return h & (length - 1 );
}
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 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 }
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)代码如下:
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 }
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)其代码如下:
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 }
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与上同
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 }
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 }
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 }