论坛首页 入门技术论坛

这个循环太让人郁闷了

浏览 12406 次
该帖已经被评为新手帖
作者 正文
   发表时间:2009-04-03  
StringBuffer用于多线程,单线程使用StringBuilder会更快。
0 请登录后投票
   发表时间:2009-04-03  
RednaxelaFX 写道
night_stalker 写道
弱问加 1 的意义何在……

印象中在哪里看到过这个设计理由的……嗯我想不起来了。但Sun的JDK里就是这么实现的 =v=


这个..其实是为了对付初始容量为0的情况=v=
0 请登录后投票
   发表时间:2009-04-03  
量产型人型自走炮 写道
RednaxelaFX 写道
night_stalker 写道
弱问加 1 的意义何在……

印象中在哪里看到过这个设计理由的……嗯我想不起来了。但Sun的JDK里就是这么实现的 =v=


这个..其实是为了对付初始容量为0的情况=v=

// 初始容量==0这里也不需要+1,



public AbstractStringBuilder append(String str) {
if (str == null) str = "null";
        int len = str.length();
if (len == 0) return this;
int newCount = count + len;  // count 不小于0,len至少是1
if (newCount > value.length) // 初始是0的话,这里也>=1
    expandCapacity(newCount); // 下面
str.getChars(0, len, value, count);
count = newCount;
return this;
    }

void expandCapacity(int minimumCapacity) {
int newCapacity = (value.length + 1) * 2; // 如果不+1就可能是0
        if (newCapacity < 0) {
            newCapacity = Integer.MAX_VALUE;
        } else if (minimumCapacity > newCapacity) {          
            newCapacity = minimumCapacity;  // 这里也至少是1
}
char newValue[] = new char[newCapacity];
System.arraycopy(value, 0, newValue, 0, count);
value = newValue;
    }

0 请登录后投票
   发表时间:2009-04-03  
量产型人型自走炮 写道
RednaxelaFX 写道
night_stalker 写道
弱问加 1 的意义何在……

印象中在哪里看到过这个设计理由的……嗯我想不起来了。但Sun的JDK里就是这么实现的 =v=


这个..其实是为了对付初始容量为0的情况=v=

+1,觉得是如果count == value.length的话,
加进来不至于value满了~~
0 请登录后投票
   发表时间:2009-04-03  
有够晕,这么大量根本就不应该放在内存中。

应该直接传一个Writer进行,然后在Writer写入。
0 请登录后投票
   发表时间:2009-04-03  
用StringBuilder还可以快十几秒
0 请登录后投票
   发表时间:2009-04-03  

在看看ArrayList的扩容,newCapacity = oldCapacity *3/2+1; 大概是1.5倍,这个确保新容量至少是1。

不过考虑到AbstractStringBuilder一般都是直接加一批char,

List一般加一个(addAll特殊考虑下,用minCapacity和newCapacity )。

貌似new ArrayList(0),然后加入一个长度大于1的集合,这时List被充满了。~~

 

------------------------------------------------------------------------------------------

 

    public void ensureCapacity(int minCapacity) {
 modCount++;
 int oldCapacity = elementData.length;
 if (minCapacity > oldCapacity) {
     Object oldData[] = elementData;
     int newCapacity = (oldCapacity * 3)/2 + 1; 
         if (newCapacity < minCapacity)
  newCapacity = minCapacity;
     elementData = (E[])new Object[newCapacity];
     System.arraycopy(oldData, 0, elementData, 0, size);
 }
    }



 public boolean addAll(Collection<? extends E> c) {
 Object[] a = c.toArray();
        int numNew = a.length;
 ensureCapacity(size + numNew);  // Increments modCount  
        System.arraycopy(a, 0, elementData, size, numNew);
        size += numNew;
 return numNew != 0;
    }

 

0 请登录后投票
   发表时间:2009-04-03  

再来看看HashMap的容量扩张,因为hash要考虑寻址的效率,所以有了装填因子的概念,不能被填的太满,默认是0.75(.net的hashtable我记得好像是0.72)。

怎么也不会装满的~

初始的实际容量至少是1----initialCapacity参数为0的时候,下面这个没用:

 

// Find a power of 2 >= initialCapacity
        int capacity = 1;
        while (capacity < initialCapacity) 
            capacity <<= 1;

 不过幸运的是,每次put或是putAll的addEntry的时候,都会判断下,不够就*2~~, 为了计算hash方便,一直取2的幂:

 

void addEntry(int hash, K key, V value, int bucketIndex) {
	Entry<K,V> e = table[bucketIndex];
        table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
        if (size++ >= threshold)
            resize(2 * table.length);
    }

 

----------------------------------------

默认的初始容量问题: StringBuilder是16,ArrayList是10,HashMap是16

 

默认的容量增长:StringBuilder的是 (oldCapacity+1)*2 一直是偶数

  ArrayList是 (oldCapacity * 3)/2 + 1

HashMap是 oldCapacity*2 一直是2的幂

 

.net的hashtable是取oldCapacity*2 最接近的一个素数作为容量~~

 

0 请登录后投票
   发表时间:2009-04-03  
。。。。。每次都被lz的帖子给骗进来
0 请登录后投票
   发表时间:2009-04-03  
kimmking 写道

StringBuilder的是 (oldCapacity+1)*2 一直是偶数

总之要+1 这个+1在哪里只是具体设计的问题吧=_=
kimmking 写道

HashMap是 oldCapacity*2 一直是2的幂

其实我更关心的是他的再散列寻址....
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics