Java SE String类 (三) : StringBuilder, StringBuffer与OJ例题

2. StringBuilder和StringBuffer

在上一篇博客我们提到,String类具有不可变性,在每次修改字符串的时候都是创建新的对象去修改,那么现在我们引入StringBuilder和StringBuffer类. 在用这两个类建立对象的时候, 字符串就是可变的, 可用类中的一些方法对字符串进行一系列操作,这两个大类的部分功能是相同的.这里介绍一些常用的方法,要是用到其他方法,大家可参考jdk帮助手册.

方法功能
StringBuff append(String str)在尾部添加字符串,相当于String的+=
char charAt(int index)获取index位置的字符
int length()获取字符串的长度
int capacity()获取字符串在底层储存空间的大小
void ensureCapacity(int mininmumCapacity)扩容
int setCharAt(int index,char ch)将index位置的字符设置为ch
int indexOf(String str)将index位置开始查找str第一次出现的位置
int indexOf(String str,int index)从index位置开始向后查找str,返回第一次出现的位置
int lastIndexOf(String str)从最后的位置开始查找指定字符串
int lastIndexOf(String str,int index)从index位置开始查找指定字符串
StringBuff insert(int index,String str)在index位置插入:八种基本类型,String类,Object类
StringBuffer delete(int start,int end)删除[start,end)区间的字符串
StirnBuffer deleteCharAt(int index)删除index位置的字符
StringBuffer replace(int start,int end,String str)替换[start,end)区间的字符串
String substring(int start)从start位置截取字符串,直到结尾,并以String类型返回
String substring(int start, int end)将[start,end)范围字符串截取下来,并以String类型返回
StringBuffer reverse()翻转字符串
String toString()将所有字符串以String的方式返回
下面进行上述方法的演示
public class Test {
    public static void main(String[] args) {
        StringBuilder sb1 = new StringBuilder("hello");
        sb1.append(" world");
        sb1.append(" !!!");//为sb1添加字符
        System.out.println(sb1);
        System.out.println(sb1.charAt(2));//获取2位置的字符
        System.out.println(sb1.length());
        sb1.setCharAt(0, 'H');//,第二个参数传入字符类型,字符用单引号引起来
        System.out.println(sb1);
        System.out.println(sb1.indexOf("ell"));//,传入字符串类型返回字符串第一次出现的位置
        System.out.println(sb1.indexOf("llo",1));//从指定位置开始查找字符串
        System.out.println(sb1.lastIndexOf("rld"));//从最后开始查找字符串
        System.out.println(sb1.lastIndexOf("wor",10));//从指定位置开始向前查找字符串
        sb1.insert(1,"uuu");//在指定位置插入指定字符串
        System.out.println(sb1);
        sb1.delete(1,4);//删除[1,4)位置的字符
        System.out.println(sb1);
        sb1.deleteCharAt(1);//删除指定位置的字符
        System.out.println(sb1);
        sb1.replace(2,5,"uuu");//把指定区间的字符串替换为指定字符串
        System.out.println(sb1);
        System.out.println(sb1.substring(4));//从指定位置开始截取字符串
        System.out.println(sb1.substring(4,7));//截取指定区间的字符串
        System.out.println(sb1.reverse());
    }
}

上述例子可以看出: String和StringBuilder最大的区别就是==String内容无法修改,而StringBuilder的内容可以修改,==频繁修改字符串考虑使用StringBuilder.

注意: String和StringBuilder类不可以直接转换,如果想要转换,可以采用如下方法:

  • String变为StringBuilder: 利用StringBuiler的构造方法,或者append方法
  • StringBuilder变为String: 利用toString方法
public class Test {
    public static void main(String[] args) {
        String s1 = "hello";
        StringBuilder sb2 = new StringBuilder(s1);//调用StringBuilder的构造方法,将String转换为StringBuilder
        StringBuilder sb3 = new StringBuilder();
        sb3.append(s1);
        System.out.println(sb2);
        System.out.println(sb3);
        String s2 = sb2.toString();//利用StringBuilder的toStirng方法,将sb转换为String
        System.out.println(s2);
    }
}

面试题

  1. String类,StringBuilder和StringBuffer的区别
  • String类的内容不可以修改,但是StringBuilder和StringBuffer可以修改
  • StringBuffer采用同步处理,属于线程安全操作,而StringBuilder未采用同步处理,属于线程不安全操作

3. String类OJ

  1. 第一个只出现一次的字符
class Solution {
    public int firstUniqChar(String s) {
        int[] count = new int [256];//定义计数数组
        for(int i = 0;i < s.length();i++){
            count[s.charAt(i)]++;//存放每个字母出现的次数
        } 
        for(int i = 0;i < s.length();i++){
            if(count[s.charAt(i)] == 1){//如果出现次数为1,则返回该下标
                return i;
            }
        }
        return -1;
    }
}
  1. 最后一个单词的长度
import java.util.Scanner;
	public class Main{
		public static void main(String[] args){
		// 循环输入
			Scanner sc = new Scanner(System.in);
			while(sc.hasNext()){
				// 获取一行单词
				String s = sc.nextLine();
				// 1. 找到最后一个空格
				// 2. 获取最后一个单词:从最后一个空格+1位置开始,一直截取到末尾
				// 3. 打印最后一个单词长度
				int len = s.substring(s.lastIndexOf(' ')+1, s.length()).length();
				System.out.println(len);
			}
		sc.close();
	}
}
  1. 判断字符串是否回文
class Solution {
	public static boolean isValidChar(char ch){
	if((ch >= 'a' && ch <= 'z') ||
	(ch >= '0' && ch <= '9')){
			return true;
		}
			return false;
	}
	public boolean isPalindrome(String s) {
	// 将大小写统一起来
	s = s.toLowerCase();
	int left = 0, right = s.length()-1;
	while(left < right){
		// 1. 从左侧找到一个有效的字符
		while(left < right && !isValidChar(s.charAt(left))){
		left++;
		}
		// 2. 从右侧找一个有效的字符
		while(left < right && !isValidChar(s.charAt(right))){
		right--;
		}
		if(s.charAt(left) != s.charAt(right)){
		return false;
		}else{
		left++;
		right--;
		}
		}
		return true;
	}
}