字符串String Stringbuilder StringBuffer

一、 String Stringbuilder Stringbuffer简介

1.1 String

字符串常量,字符串长度不可变(immutable)
String 类源码(截取常用方法和属性)

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    private final char value[];
    private int hash; // Default to 0
    
    public String() {
        this.value = "".value;
    }
    
    public String(char value[]) {
        this.value = Arrays.copyOf(value, value.length);
    }

    public String(StringBuffer buffer) {
        synchronized(buffer) {
            this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
        }
    }
   
    public String(StringBuilder builder) {
        this.value = Arrays.copyOf(builder.getValue(), builder.length());
    }
    
    public int length() {
        return value.length;
    }

    public boolean isEmpty() {
        return value.length == 0;
    }
    
    public char charAt(int index) {
        if ((index < 0) || (index >= value.length)) {
            throw new StringIndexOutOfBoundsException(index);
        }
        return value[index];
    }
    
    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

    //判断字符串是否已prefix为开头
    public boolean startsWith(String prefix) {
        return startsWith(prefix, 0);
    }

    //判断字符串是否以suffix为结尾
    public boolean endsWith(String suffix) {
        return startsWith(suffix, value.length - suffix.value.length);
    }
    
    //根据字符串开始下标截取
    public String substring(int beginIndex) {
        if (beginIndex < 0) {
            throw new StringIndexOutOfBoundsException(beginIndex);
        }
        int subLen = value.length - beginIndex;
        if (subLen < 0) {
            throw new StringIndexOutOfBoundsException(subLen);
        }
        return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
    }
    
    //根据开始和结束下标截取字符串的部分
    public String substring(int beginIndex, int endIndex) {
        if (beginIndex < 0) {
            throw new StringIndexOutOfBoundsException(beginIndex);
        }
        if (endIndex > value.length) {
            throw new StringIndexOutOfBoundsException(endIndex);
        }
        int subLen = endIndex - beginIndex;
        if (subLen < 0) {
            throw new StringIndexOutOfBoundsException(subLen);
        }
        return ((beginIndex == 0) && (endIndex == value.length)) ? this
                : new String(value, beginIndex, subLen);
    }
    
    public String toString() {
        return this;
    }
    
    //将字符串的大写字母换为小写
    public String toLowerCase() {
        return toLowerCase(Locale.getDefault());
    }
    
    //将字符串的小写字母转为大写
    public String toUpperCase() {
        return toUpperCase(Locale.getDefault());
    }
    
    // 去除字符串前后空格
    public String trim() {
        int len = value.length;
        int st = 0;
        char[] val = value;    /* avoid getfield opcode */

        while ((st < len) && (val[st] <= ' ')) {
            st++;
        }
        while ((st < len) && (val[len - 1] <= ' ')) {
            len--;
        }
        return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
    }
}
1.2 StringBuffer

字符串变量(Synchronized,即线程安全)。如果要频繁对字符串内容进行修改,出于效率考虑最好使用 StringBuffer,转成 String 类型,调用 StringBuffer 的 toString() 方法即可。
主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。其中append 方法始终将这些字符添加到缓冲区的末端;insert 方法则在指定的点添加字符。
StringBuffer 类源码(截取部分常用的属性和方法)

 public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{
    private transient char[] toStringCache;
    public StringBuffer(String str) {
        super(str.length() + 16);
        append(str);
    }
   
    @Override
    public synchronized int length() {
        return count;
    }
    
    @Override
    public synchronized char charAt(int index) {
        if ((index < 0) || (index >= count))
            throw new StringIndexOutOfBoundsException(index);
        return value[index];
    }

    @Override
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }
    
    public synchronized StringBuffer append(StringBuffer sb) {
        toStringCache = null;
        super.append(sb);
        return this;
    }

    @Override
    public synchronized StringBuffer replace(int start, int end, String str) {
        toStringCache = null;
        super.replace(start, end, str);
        return this;
    }
    
    @Override
    public synchronized StringBuffer insert(int offset, String str) {
        toStringCache = null;
        super.insert(offset, str);
        return this;
    }
    
    @Override
    public synchronized StringBuffer reverse() {
        toStringCache = null;
        super.reverse();
        return this;
    }
    
    @Override
    public synchronized String substring(int start) {
        return substring(start, count);
    }

    public synchronized String substring(int start, int end) {
        return super.substring(start, end);
    }
    
    @Override
    public synchronized String toString() {
        if (toStringCache == null) {
            toStringCache = Arrays.copyOfRange(value, 0, count);
        }
        return new String(toStringCache, true);
    }
}
1.3 StringBuilder

StringBuilder 类源码(截取部分常用的属性和方法)

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

}
1.4 三者区别

String 类型和 StringBuffer 的主要性能区别:String 是不可变的对象, 因此在每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,性能就会降低。
使用 StringBuffer 类时,每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。所以多数情况下推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。

二、编程题(来自牛客网)

2.1 字符串变形

对于一个长度为 n 字符串,我们需要对它做一些变换。首先这个字符串中包含着一些空格,就像"Hello World"一样,然后我们要做的是把这个字符串中由空格隔开的单词反序,同时反转每个字符的大小写。比如"Hello World"变形后就变成了 “wORLD hELLO”。
如输入:"This is a sample",16
输出:"SAMPLE A IS tHIS"

思路分析:字符串需要变化多次,使用StringBuffer存储,使用到StringBuffer的append()添加,reverse()反转,substring()截取,toString()转为String和replace()代替。代码程序步骤如下:
1,反转大小写
2,反序字符串,根据空格再次反序单词

public class Solution {
    public String trans(String s, int n) {
        if(n == 0)
            return s;
        // write code here
        StringBuffer result = new StringBuffer();
        //1.反转大小写
        for(int i=0; i<n; i++){
            if(s.charAt(i) >= 'a' && s.charAt(i) <= 'z'){
                //小写字母换为大写
                result.append((char)(s.charAt(i) - 'a' + 'A'));
            }else if(s.charAt(i) >= 'A' && s.charAt(i) <= 'Z'){
                //大写字母换为小写
                result.append((char)(s.charAt(i)- 'A' + 'a'));
            }else{
                //其它字符直接写入
                result.append(s.charAt(i));
            }
        }

        //2.反序字符串,根据空格二次反序单词
        result = result.reverse(); //第一次反序
        for(int i=0; i<n; i++){
            int in1 = i;
            //根据空格再次反序 并替换
            while(i<n && result.charAt(i) != ' ')
              i++;
            StringBuffer temp = new StringBuffer(result.substring(in1, i));
            result.replace(in1, i, temp.reverse().toString());
        }

        return result.toString();
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值