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);
}
}
面试题
- String类,StringBuilder和StringBuffer的区别
- String类的内容不可以修改,但是StringBuilder和StringBuffer可以修改
- StringBuffer采用同步处理,属于线程安全操作,而StringBuilder未采用同步处理,属于线程不安全操作
3. String类OJ
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;
}
}
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();
}
}
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;
}
}