String
在熟背的八大数据类型中,String是不存在的;String表示字符串类型,属于 引用数据类型
,不属于基本数据类型。
String类的特点
-
字符串不可变,它们的值在创建后不能被更改
-
虽然 String 的值是不可变的,但是它们可以被共享
-
字符串效果上相当于字符数组( char[] ),但是底层原理是字节数组( byte[] )
String类的构造方法
- 常用的构造方法
public String() | 创建一个空白字符串对象,不含有任何内容 |
public String(char[] chs) | 根据字符数组的内容,来创建字符串对象 |
public String(byte[] bys) | 根据字节数组的内容,来创建字符串对象 |
String s = “abc”; | 直接赋值的方式创建字符串对象,内容就是abc |
public static void main(String[] args) {
//public String():创建一个空白字符串对象,不含有任何内容
String s1 = new String();
System.out.println("s1:" + s1);
//public String(char[] chs):根据字符数组的内容,来创建字符串对象
char[] chs = {'a', 'b', 'c'};
String s2 = new String(chs);
System.out.println("s2:" + s2);
//public String(byte[] bys):根据字节数组的内容,来创建字符串对象
byte[] bys = {97, 98, 99};
String s3 = new String(bys);
System.out.println("s3:" + s3);
//String s = “abc”; 直接赋值的方式创建字符串对象,内容就是abc
String s4 = "abc";
System.out.println("s4:" + s4);
}
String类提供了许多的方法对字符串进行操作
charAt(int index) 返回指定索引处的 char 值。 |
concat(String str) 将指定字符串连接到此字符串的结尾。 |
contains(CharSequence s) 当且仅当此字符串包含指定的 char 值序列时,返回 true。 |
endsWith(String suffix) 测试此字符串是否以指定的后缀结束。 |
equals(Object anObject) 将此字符串与指定的对象比较。 |
getBytes() 使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。 |
getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) 将字符从此字符串复制到目标字符数组。 |
hashCode() 返回此字符串的哈希码。 |
indexOf(int ch) 返回指定字符在此字符串中第一次出现处的索引。 |
lastIndexOf(int ch) 返回指定字符在此字符串中最后一次出现处的索引。 |
lastIndexOf(String str, int fromIndex) 返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。 |
length() 返回此字符串的长度。 |
replace(char oldChar, char newChar) 返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。 |
split(String regex) 根据给定正则表达式的匹配拆分此字符串。 |
startsWith(String prefix) 测试此字符串是否以指定的前缀开始。 |
substring(int beginIndex, int endIndex) 返回一个新字符串,它是此字符串的一个子字符串。 |
toLowerCase() 使用默认语言环境的规则将此 String 中的所有字符都转换为小写。 |
toUpperCase() 使用默认语言环境的规则将此 String 中的所有字符都转换为大写。 |
trim() 返回字符串的副本,忽略前导空白和尾部空白。 |
valueOf(Object obj) 返回 Object 参数的字符串表示形式。 |
方法的具体演示:
String str="123456abc";
String str1=new String("123456abc");
System.out.println(str.equals("123abcd"));//打印为false
System.out.println(str.equals("123456abc"));//打印为true
System.out.println(str.length());//打印为9
System.out.println(str.charAt(1));//打印为2
System.out.println(str.indexOf("3"));//打印为2
System.out.println(str.indexOf("3"));//打印为2
char[] chars = str.toCharArray();
for (int i=0;i<chars.length;i++){
System.out.println(chars[i]);
}//输出结果为一个字符一行的打印
String sr="Signal-strength";
String s = sr.toUpperCase();
System.out.println(s);//打印为SIGNAL-STRENGTH
String sr="Signal-strength";
String s = sr.toLowerCase();
System.out.println(s);//打印为signal-strength
String str="123_456";
String[] s = str.split("_");
for (String s1:s){
System.out.println(s1);
}
//打印为
// 123
// 456
String str=" 1 23_456 ";
System.out.println(str);
System.out.println(str.trim());
String str="123_456";
System.out.println(str.substring(0,3));//不包含3
System.out.println(str.substring(2));//从第3个位置截取
String str="absC";
String str1="absc";
System.out.println(str.concat(str1));//打印为absCabsc
String str="absCac";
System.out.println(str.startsWith("ab"));//打印为true
String str="absCac";
System.out.println(str.startsWith("ab"));//打印为true
String s = String.valueOf(21);
System.out.println(s);//打印为21
StringBuffer和StringBuilder
StringBuffer、StringBuilder和String类似,底层也是用一个数组来存储字符串的值,并且数组的默认长度为16,即一个空的StringBuffer对象数组长度为16。实例化一个StringBuffer对象即创建了一个大小为16个字符的字符串缓冲区。但是当我们调用有参构造函数创建一个StringBuffer对象时,数组长度就不再是16了,而是根据当前对象的值来决定数组的长度,数组的长度为“当前对象的值的长+16”。所以一个 StringBuffer 创建完成之后,有16个字符的空间可以对其值进行修改。如果修改的值范围超出了16个字符,会先检查StringBuffer对象的原char数组的容量能不能装下新的字符串,如果装不下则会对 char 数组进行扩容。
那StringBuffer是怎样进行扩容的呢?
扩容的逻辑就是创建一个新的 char 数组,将现有容量扩大一倍再加上2,如果还是不够大则直接等于需要的容量大小。扩容完成之后,将原数组的内容复制到新数组,最后将指针指向新的 char 数组。
StringBuffer和StringBuilder中常用的方法:
StringBuffer append(xxx):拼接字符串
StringBuffer delete(int start,int end):删除指定范围的内容,左开右闭
StringBuffer replace(int start, int end, String str):替换指定范围的内容
StringBuffer insert(int offset, xxx):在指定位置插入指定的内容
StringBuffer reverse() :把当前字符序列逆转
public int indexOf(String str) : 返回指定子字符串在当前字符串中第一次出现处的索引
public String substring(int start,int end) :返回指定范围的子字符串
public int length() : 返回字符串的长度
public char charAt(int n ) : 获取指定索引处的字符
public void setCharAt(int n ,char ch) : 设置指定索引处的字符
StringBuilder str = new StringBuilder("我是");
// 拼接字符串
str.append("美女");
System.out.println(str);
// 添加字符串
str.insert(2,"超级");
System.out.println(str);
// 颠倒
// str.reverse();
System.out.println(str);
// 删除从2-4(不包括4)
str.delete(2,4);
System.out.println(str);
// 将下标为2的字符改为“=”
str.setCharAt(2,'=');
System.out.println(str);
String、StringBuffer和StringBuilder的异同?
相同点:底层都是通过char数组实现的
不同点:
1、String对象一旦创建,其值是不能修改的,如果要修改,会重新开辟内存空间来存储修改之后的对象;而StringBuffer和StringBuilder对象的值是可以被修改的;
2、StringBuffer几乎所有的方法都使用synchronized实现了同步,线程比较安全,在多线程系统中可以保证数据同步,但是效率比较低;而StringBuilder 没有实现同步,线程不安全,在多线程系统中不能使用 StringBuilder,但是效率比较高。
3、如果我们在实际开发过程中需要对字符串进行频繁的修改,不要使用String,否则会造成内存空间的浪费;当需要考虑线程安全的场景下使用 StringBuffer,如果不需要考虑线程安全,追求效率的场景下可以使用 StringBuilder。