StringBuilder/Buffer_api

实现继承

public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence{}

AbstractStringBuilder

扩容

 private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0) {
            value = Arrays.copyOf(value,
                    newCapacity(minimumCapacity));
        }
    }

append(直接在尾部)

添加 字符数组

public AbstractStringBuilder append(char str[]) { 
    int newCount = count + str.length;
    if (newCount > value.length)
        expandCapacity(newCount);
        System.arraycopy(str, 0, value, count, str.length);
        count = newCount;
        return this;
    }

// 添加 boolean 
public AbstractStringBuilder append(boolean b) {
        if (b) {
            int newCount = count + 4;
            if (newCount > value.length)
                expandCapacity(newCount);
            value[count++] = 't';
            value[count++] = 'r';
            value[count++] = 'u';
            value[count++] = 'e';
        } else {
            int newCount = count + 5;
            if (newCount > value.length)
                expandCapacity(newCount);
            value[count++] = 'f';
            value[count++] = 'a';
            value[count++] = 'l';
            value[count++] = 's';
            value[count++] = 'e';
        }
            return this;
    }
    
// 添加 Integer
 public AbstractStringBuilder append(int i) {
        if (i == Integer.MIN_VALUE) {
            append("-2147483648");
            return this;
        }
        int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1
                                     : Integer.stringSize(i);                           
        // 需要知道Integer字符串所需长度,因为插入是从尾部开始向前插,
        int spaceNeeded = count + appendedLength;
        ensureCapacityInternal(spaceNeeded);
        
        Integer.getChars(i, spaceNeeded, value);
        count = spaceNeeded;
        return this;
    }

// Integer的getchar
 static void getChars(int i, int index, char[] buf) {
        int q, r;
        int charPos = index;
        char sign = 0;

        if (i < 0) {
            sign = '-';
            i = -i;
        }
        // Generate two digits per iteration
        while (i >= 65536) {
            q = i / 100;
        // really: r = i - (q * 100);
        // r 是后两位
            r = i - ((q << 6) + (q << 5) + (q << 2));
            i = q;
            //  一次获取两位。。
            buf [--charPos] = DigitOnes[r];
            buf [--charPos] = DigitTens[r];
        }

        // Fall thru to fast mode for smaller numbers
        // assert(i <= 65536, i);
        for (;;) {
        	// 不是直接/10
            q = (i * 52429) >>> (16+3);
            // 不是直接取余
            r = i - ((q << 3) + (q << 1));  // r = i-(q*10) ...
            buf [--charPos] = digits [r];
            i = q;
            if (i == 0) break;
        }
        if (sign != 0) {
            buf [--charPos] = sign;
        }
    }

insert (允许指定插入位置)

// 在value[]的下标为index位置插入数组str的[offset,offset+len)部分;
 public AbstractStringBuilder insert(int index, char str[], int offset,
                                        int len)
    {
        if ((index < 0) || (index > length()))
        throw new StringIndexOutOfBoundsException(index);
        if ((offset < 0) || (len < 0) || (offset > str.length - len))
            throw new StringIndexOutOfBoundsException(
                "offset " + offset + ", len " + len + ", str.length " 
                + str.length);
    int newCount = count + len;
    if (newCount > value.length)
        expandCapacity(newCount);
    // 腾出 len 的空余长度 ,将count - index 长度的挪到后面
    System.arraycopy(value, index, value, index + len, count - index);
    //  插入数据
    System.arraycopy(str, offset, value, index, len);
    count = newCount;
    return this;
    }

replace 修改

// replace(int start, int end, String str):
// 用字符串str替换掉value[]数组的[start,end)部分
 public AbstractStringBuilder replace(int start, int end, String str) {
 	// 保证不越界
    if (start < 0)
        throw new StringIndexOutOfBoundsException(start);
    if (start > count)
        throw new StringIndexOutOfBoundsException("start > length()");
    if (start > end)
        throw new StringIndexOutOfBoundsException("start > end");

    if (end > count)
        end = count;
    int len = str.length();
    // 替换后的长度 
    int newCount = count + len - (end - start);
    if (newCount > value.length)
        expandCapacity(newCount);

        System.arraycopy(value, end, value, start + len, count - end);
        str.getChars(value, start);
        count = newCount;
        return this;
    }

index(找到子串下标)

// fromIndex开始,在value[]中找字符串str,若能找到,返回第一个字符串的第一个字符的下标

public int indexOf(String str, int fromIndex) {
        return String.indexOf(value, 0, count,
                              str.toCharArray(), 0, str.length(), fromIndex);
    }
    
// lastIndexOf(String str, int fromIndex):从后往前到fromIndex,找子串str
 public int lastIndexOf(String str, int fromIndex) {
        return String.lastIndexOf(value, 0, count,
                              str.toCharArray(), 0, str.length(), fromIndex);
    }

// string的 indexof
static int indexOf(char[] source, int sourceOffset, int sourceCount,
            char[] target, int targetOffset, int targetCount,
            int fromIndex) {
        if (fromIndex >= sourceCount) {
            return (targetCount == 0 ? sourceCount : -1);
        }
        if (fromIndex < 0) {
            fromIndex = 0;
        }
        if (targetCount == 0) {
            return fromIndex;
        }

        char first = target[targetOffset];
        // 查子串的终点
        int max = sourceOffset + (sourceCount - targetCount);

        for (int i = sourceOffset + fromIndex; i <= max; i++) {
            /* Look for first character. */
            // 找到第一个首节点
            if (source[i] != first) {
                while (++i <= max && source[i] != first);
            }

            /* Found first character, now look at the rest of v2 */
            if (i <= max) {
            	// 查询起始点
                int j = i + 1;
                // 查询结束点
                int end = j + targetCount - 1;
                // 判断当前 index 是否
                for (int k = targetOffset + 1; j < end && source[j]
                        == target[k]; j++, k++);

                if (j == end) {
                    /* Found whole string. */
                    return i - sourceOffset;
                }
            }
        }
        return -1;
    }

方法

大多数直接使用抽象父类的方法 少部分抽象方法重写

//abstractstringbuilder
public abstract String toString();

// StringBuilder
public String toString() {
     // Create a copy, don't share the array
     return new String(value, 0, count);
 }

// StringBuffer

 public synchronized String toString() {
        if (toStringCache == null) {
            toStringCache = Arrays.copyOfRange(value, 0, count);
        }
        return new String(toStringCache, true);
    }

synchronized 关键字

修饰实例方法 对当前实例加锁
修饰静态方法 对当前类对象加锁
修饰代码块 对指定对象加锁

相关的一些 wait、notify、notifyAll(object 的方法)

因为synchronized 就是对 对象进行加锁,

// 锁池:假设线程A已经拥有了某个对象(注意:不是类)的锁,而其它的线程想要调用这个对象的某个synchronized方法(或者synchronized块),由于这些线程在进入对象的synchronized方法之前必须先获得该对象的锁的拥有权,但是该对象的锁目前正被线程A拥有,所以这些线程就进入了该对象的锁池中。

// 等待池:假设一个线程A调用了某个对象的wait()方法,线程A就会释放该对象的锁后,进入到了该对象的等待池中
// 链接:https://www.zhihu.com/question/37601861/answer/145545371
// 假设一个线程A调用了某个对象的wait()方法,线程A就会释放该对象的锁(因为wait()方法必须出现在synchronized中,这样自然在执行wait()方法之前线程A就已经拥有了该对象的锁),同时线程A就进入到了该对象的等待池中。如果另外的一个线程调用了相同对象的notifyAll()方法,那么处于该对象的等待池中的线程就会全部进入该对象的锁池中,准备争夺锁的拥有权。如果另外的一个线程调用了相同对象的notify()方法,那么仅仅有一个处于该对象的等待池中的线程(随机)会进入该对象的锁池.
// notify方法只唤醒一个等待(对象的)线程并使该线程开始执行。所以如果有多个线程等待一个对象,这个方法只会唤醒其中一个线程,选择哪个线程取决于操作系统对多线程管理的实现。notifyAll 会唤醒所有等待(对象的)线程,尽管哪一个线程将会第一个处理取决于操作系统的实现。如果当前情况下有多个线程需要被唤醒,推荐使用notifyAll 方法。比如在生产者-消费者里面的使用,每次都需要唤醒所有的消费者或是生产者,以判断程序是否可以继续往下执行。

 public final native void notify();

public final native void notifyAll();

// 让持有对象锁的线程准备释放对象锁权限,释放cpu资源并进入等待

public final native void wait(long timeout) throws InterruptedException;


public final void wait(long timeout, int nanos) throws InterruptedException {
        if (timeout < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }

        if (nanos > 0) {
            timeout++;
        }

        wait(timeout);
    }
public class sychronized_demo implements Runnable{
    public void run() {
    }

    public static class WaitAndNotify {
        public static void main(String[] args) {
            Object co = new Object();
            System.out.println(co);

            for (int i = 0; i < 5; i++) {
                MyThread t = new MyThread("Thread" + i, co);
                t.start();
            }

            try {
                TimeUnit.SECONDS.sleep(2);
                System.out.println("-----Main Thread notify-----");
                synchronized (co) {
                    // 如果是notify, 只有一个线程从等待池进入锁池,然而只有在锁池才能竞争锁
                    // 等待池中的线程不会去竞争该对象的锁
                    // 所以如果竞争到锁的进程 执行后续代码 没有notify函数,其他线程就会在 等待池 卡住
                    co.notifyAll();
                }
                MyThread t = new MyThread("Thread88" , co);
                t.start();
                TimeUnit.SECONDS.sleep(2);
                System.out.println("Main Thread is end.");

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        static class MyThread extends Thread {
            private String name;
            private Object co;

            public MyThread(String name, Object o) {
                this.name = name;
                this.co = o;
            }

            @Override
            public void run() {
                System.out.println(name + " is waiting.");
                try {
                    synchronized (co) {
                        co.wait();
                        System.out.println(this.name+" is awaken");
                    }
                    System.out.println(name + " has been notified.");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值