【JAVA_SE学习笔记】String、StringBuffer和StringBuilder
String
String类:代表字符串。Java 程序中的所有字符串字面值(如 “abc” )都作为此类的实例实现;字符串一旦被赋值,其值不能再改变
String类常用的构造方法:
1.String():表示一个空字符序列
2.public String(byte[] bytes,Charset ch):默认字符集(编码格式):GBK,如果是GBK格式,可以不写第二个参数
3.public String(byte[] bytes,int index,int length):将部分字节数组构造成一个字符串
4.public String(char[] value):将字符数组构造成一个字符串
5.public String(char[] value,int index,int length):将部分的字符数组构造成一个字符串
6.public String(String original):通过字符串常量构造一个字符串对象
7.public String(StringBuffer buffer):字符缓冲区到字符
编码解码:
编码:把能看懂的东西转换成一个看不懂的东西:String—–>byte[]:public byte[] getBytes(String charsetName)
解码:把当前的byte[]转成能看懂的东西(String):byte[]—–>String :public String(byte[] bytes,CharsetName ch)
题目:
public class Demo1 {
public static void main(String[] args) {
String str1 = "hello";
String str2 = "hello";
String str3 = new String("hello");
String str4 = new String("hello");
System.out.println("str1==str2?"+(str1==str2)); //true
System.out.println("str2==str3?"+(str2==str3)); //false
System.out.println("str3==str4?"+(str3==str4)); // false
System.out.println("str2.equals(str3)?"+(str2.equals(str3))); // true
System.out.println("str3.equals(str4)?"+(str3.equals(str4))); //true
/*
String类已经重写了Object的equals方法,比较的是两个字符串的内容是否一致,如果一致
则返回true,否则返回false
*/
}
}
面试题:
String s = “hello”和String s = new String(“hello”) 两个有什么区别?分别创建了几个对象?
第一个创建了一个对象
第二个s创建两个对象(堆内存中有new String(),然后字符串常量池中也有这样一个字符串常量(开辟空间的地址))
字符串的一个特点:一旦被赋值,其值不能被改变(不可变的字符序列)
String类型作为形式参数和基本数据类型的效果一样
public class Demo3 {
public static void main(String[] args) {
String s = "hello" ; // String s = "abc" ;
/* s += "world" ;
System.out.println("s:"+s);//s:helloworld
*/
change(s) ;
//输出字符串变量
System.out.println("s:"+s);//s:hello
}
public static void change(String s) {//String类型作为形式参数和基本数据类型的效果一样
s += "javaweb" ;
}
}
字符串变量相加:先开辟空间,在相加
字符串常量相加:首先在字符串常量池找,有没有当前这个常量值,有,就直接返回,没有,需要创建!
public class StringDemo2 {
public static void main(String[] args) {
String s1 = "hello";
String s2 = "world";
String s3 = "helloworld";
System.out.println(s3 == s1 + s2);// false
//System.out.println(s3 == (new StringBuilder(String.valueOf(s1))).append(s2).toString());
// s1+s2 ====>new String("helloworld")
System.out.println(s3.equals((s1 + s2)));//true ,
System.out.println(s3 == "hello" + "world");//true
System.out.println(s3.equals("hello" + "world"));//true
/**
* 通过反编译工具查看第三个输出语句:
* System.out.println(s3 == "helloworld");
System.out.println(s3.equals("helloworld"));
* */
}
}
String类常用方法
获取方法:
1. int length():获取字符串的长度
2. char charAt(int index):返回的是索引处对应的字符
3. int indexOf(int ch):返回指定字符在此字符串中第一次出现处的索引
int indexOf(String str):返回指定子字符串在此字符串中第一次出现的索引
int indexOf(int ch,int fromIndex):返回在此字符串中第一次出现指定字符处的索引,从指定的索引开始搜索。
int indexOf(String str,int fromIndex):返回在此字符串中第一次出现指定字符串处的索引,从指定的索引开始搜索
4. String substring(int start):从指定位置开始截取字符串,默认截取到末尾
String substring(int start,int end):从指定位置开始截取到指定位置结束,包前(start索引)不包后(end索引)
举例:
public class Demo3 {
public static void main(String[] args) {
char [] ch=new char[]{'世','界','和','平','和','平'};
String s=new String(ch);
System.out.println(s.length());//6
System.out.println(s.charAt(2));//和
System.out.println(s.indexOf("和平"));//2
System.out.println(s.indexOf("和平", 3));//4
System.out.println(s.substring(1,3));//界和
}
}
判断方法:
1. boolean endsWith(String str):是否以指定字符串结束
2. boolean isEmpty():是否长度为0,即是否为空
String s = “” ;空字符
String s = ” ” ;字符串”空格”
String s = null ;当前字符串对象为空
3. boolean startsWith():是否以指定字符串开始
4. boolean contains (Char Sequences):是否包含指定的序列
5. boolean equals (Object anObject):判断的内容是否一致
6. boolean equalsIgnoreCase(String anotherString):忽略大小写比较是否一致
举例:
public class Demo4 {
public static void main(String[] args) {
String s="helloWorldJava";
String s2="HELLOWORLDJAVA";
System.out.println(s.endsWith("ava"));//true
System.out.println(s.isEmpty());//false
System.out.println(s.startsWith("Ja"));//false
System.out.println(s.contains("World"));//true
System.out.println(s.equals(s2));//false
System.out.println(s.equalsIgnoreCase(s2));//true
}
}
转换方法:
1. char [ ] toCharArray():将字符串转换为字符数组
2. getBytes();转换为字节数组
3. String valueOf():将其他数据类型或对象转为String
举例:
import java.util.Arrays;
public class Demo5 {
public static void main(String[] args) {
String s="今天是个学习的好天气";
char [] ch=s.toCharArray();
System.out.println(Arrays.toString(ch));//[今, 天, 是, 个, 学, 习, 的, 好, 天, 气]
byte [] by=s.getBytes();
System.out.println(Arrays.toString(by));//[-67, -15, -52, -20, -54, -57, -72, -10, -47, -89, -49, -80, -75, -60, -70, -61, -52, -20, -58, -8]
System.out.println(String.valueOf(ch));//今天是个学习的好天气
}
}
其他方法:
1. public String replace(char oldChar,char newChar):将字符串中某一个字符用新的字符替换
public String replace(String oldStr,String newStr):将字符串中某一个子字符串用新的字符串去替代
2. public String split(String regex):切割
3. public String trim():去除字符串两端空格
4. public int compareTo(String anotherString) 是Comparable接口中的方法(该接口可以实现一个自然排序)
如果两个字符串比较前边都一样则返回两字符串长度的差值,否则则返回第一个两个不同字符的差值
5. public String toUpperCase():转大写
6. public String toLowerCase():转小写
7. public String concat(String str):字符串拼接
举例:
public class Demo6 {
public static void main(String[] args) {
String s="This is great";
String s2=" nihao ";
String s3="This is";
String s4="Tgis is";
System.out.println(s.replaceAll("great", "bad"));//This is bad
System.out.println(s.toLowerCase());//this is great
System.out.println(s.toUpperCase());//THIS IS GREAT
System.out.println(s2.trim());//nihao
System.out.println(s.compareTo(s3));//6 都相同返回字符串的差值
System.out.println(s.compareTo(s4));//1 不相同则返回第一个两不相同字符的差值
System.out.println(s.concat(s3));//This is greatThis is
}
}
StringBuffer
字符串内容一旦创建,则不允许改变,如果一但改变就会创建一个新的字符串对象,如需改动字符串内容:可以使用字符串缓冲区
字符串缓冲区:存储字符串的集合容器
面试题: StringBuffer和String 的区别?
StringBuffer会构造一个字符串缓冲区,从内存角度考虑,一般情况使用StringBuffer比较多(在单线程程序中使用StringBulider替代,StringBuffer:线程不安全,单线程单纯为了提供执行效率!)
String:普通的一个字符串,从内存角度考虑,耗费空间!
StringBuffer的构造方法:
1. public StringBuffer ()构造一个其中不带字符的字符串缓冲区,其初始容量为 16 个字符
2. public StringBuffer(int capacity)构造一个不带字符,但具有指定初始容量的字符串缓冲区
3. public StringBuffer(String str)构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容。该字符串的初始容量为 16 加上字符串参数的长度
面试题:使用StringBuffer无参的构造方法默认的初始化容量是多少?当容量不够用时自动增加多少?
StringBuffer的底层是维护了一个字符数组,存储字符的时候实际上是往该字符数组中存储,而字符数组的初始容量是16,当容量不够时,自动增加一倍。
举例:
public class Demo1 {
public static void main(String[] args) {
StringBuffer sb1=new StringBuffer();
System.out.println("sb.length:"+sb1.length());//0 获取字符串长度
System.out.println("sb.capacity:"+sb1.capacity());//16 获取字符缓冲区容量
StringBuffer sb2=new StringBuffer("hello");
System.out.println("sb.length:"+sb2.length());//5
System.out.println("sb.capacity:"+sb2.capacity());//21 默认为初始容量16+当前字符串长度
StringBuffer sb3=new StringBuffer(32);
System.out.println("sb.length:"+sb3.length());//0
System.out.println("sb.capacity:"+sb3.capacity());//32
}
}
StringBuffer常用的方法:
增:
1. StringBuffer(“jack”)在创建对象时赋值
2. public StringBuffer append(int/String/char/boolean/double/float….)在缓冲区的尾部增加新的文本对象,可以追加各种数据
3. public StringBuffer insert(int offset,String str)在指定下标位置增加新的文本对象
举例:
public class Demo2 {
public static void main(String[] args) {
StringBuffer sb=new StringBuffer("hello");
System.out.println(sb.append("world"));//helloworld
System.out.println(sb.append(true));//helloworldtrue 各种数据都可追加
System.out.println(sb.insert(3,"JAVA"));//helJAVAloworldtrue
}
}
删:
1. public StringBuffer delete(int start,int end)删除从指定位置开始到指定位置结束的字符,返回的是字符串缓冲区本身
start开始,end-1结束
2. public StringBuffer deleteCharAt(int index)删除指定位置处的字符,返回的是字符串缓冲区本身
举例:
public class Demo3 {
public static void main(String[] args) {
StringBuffer sb=new StringBuffer("helloJAVA");
System.out.println(sb.delete(2, 5));//heJAVA
System.out.println(sb.deleteCharAt(4));//heJAA
}
}
查:
1. public String toString(StringBuffer sb)返回这个容器的字符串
2. indexOf(String str)返回第一次出现的指定字符串在该字符串中的索引
3. lastIndexOf(String str)返回最后一次出现指定字符串的索引
举例:
public class Demo4 {
public static void main(String[] args) {
StringBuffer sb=new StringBuffer("helloJAVAworldJAVA");
System.out.println(sb.toString());//helloJAVAworldJAVA
System.out.println(sb.indexOf("JAVA"));//5
System.out.println(sb.lastIndexOf("JAVA"));//14
}
}
改:
1. public String substring(int start):从指定位置默认截取到末尾,返回值是一个新的字符串
public String substring(int start,int end):从指定位置开始截取到指定位置结束,包前不包后,返回一个新的字符串
2. public StringBuffer replace(int start, int end,String str)从指定位置开始到指定位置结束的字符用str子字符串去替代
3. setCharAt(int index,char ch)指定索引位置替换一个字符
举例:
public class Demo5 {
public static void main(String[] args) {
StringBuffer sb=new StringBuffer("helloworld");
System.out.println(sb.replace(5, sb.length(), "java"));//hellojava
sb.setCharAt(5, '$');//返回值是void
System.out.println(sb);//hello$ava
System.out.println(sb.substring(0,5));//hello
}
}
面试题: StringBuffer和数组的区别?
共同特点:都属于容器类型的变量
不同点:数组:只能存储同一种数据类型的元素,数组的长度是固定的
StringBuffer:字符串缓冲区,可以存储任意类型的元素,可以不断的去给缓冲区中追加(append),字符串缓冲区中:在内存始终返回的字符串
练习:
public class StringBufferTest3 {
public static void main(String[] args) {
//创建键盘录入对象
Scanner sc = new Scanner(System.in) ;
//录入并接收
System.out.println("请您输入一个字符串:");
String str = sc.nextLine() ;
//方式1:使用String类型进行拼接
String result = myReverse(str) ;
System.out.println("result:"+result);
//方式2:使用StringBuffer的reverse()功能
String result2 = myReverse2(str) ;
System.out.println("result2:"+result2);
}
//StringBuffer的reverse()方法实现
public static String myReverse2(String s){
//创建字符串缓冲区对象h
/*StringBuffer sb = new StringBuffer(s) ;
//开始调用反转功能
sb.reverse() ;
//返回
return sb.toString() ;*/
//一步完成:
return new StringBuffer(s).reverse().toString() ;
}
//String类型的方式进行反转
public static String myReverse(String s){
//定义空串
String result = "" ;
//可以字符组其转成字符数组
char[] chs = s.toCharArray() ;
//倒着遍历
for(int x = chs.length-1 ; x >=0 ; x --){
//空串进行拼接
result += chs[x] ;
}
return result ;
}
}
StringBuilder
StringBuilder与StringBuffer的方法是一样的
笔试题目: StringBuilder与StringBuffer的区别?
相同点:都是字符串缓冲区,底层都是维护一个字符数组用于存储数据
不同点:1.StringBuffer是线程安全的,操作效率低;StringBuilder是线程非安全的,操作效率高
线程不安全:多线程中多人操作同一代码,可能执行会出现错误
线程不安全:线程安全的代码在一个时间段内只能由一个线程去操作代码
2.StringBuffer是jdk1.0出现的
StringBuilder是jdk1.5出现的