String类:
-
1、java中规定,双引号括起来的字符串是不可变的,,也就是说“abc”自出生到死亡,不可变,不能变成“abcd”,也不能变成“ab”
-
2、java中使用双引号括起来的都是String对象。例如:“abc”,“def”,“HelloWorld!”,这是三个String对象;
-
3、在JDk中双引号括起来的字符串,例如"abc","def"都是直接存储在方法区的字符串常量池中的,因为常量使用比较频繁,为了提高效率就把字符串放到了方法区;
分析:使用new的方式创建字符串对象。凡是双引号括起来的都在字符串常量池中有一份;new对象的时候一定在堆内存中开辟空间;比如:
Stringi = new String(“abc”);
其中在方法区常量池中生成“abc”,堆内存在开闭一块空间,指向方法区中“abc”的地址,在栈中的方法内有String i指向堆内存中的地址。常用的String类构造方法:
1、String s = new String(“abc”);
2、String s = new String(char数组);
3、String s = new String(bety数组);
4、String s = newString(char数组,起始下标,长度);
5、String s = new String(byte数组,起始下标,长度);
String类常用方法:
int compareTo(String anotherString) //按字典顺序比较两个字符串。"abc".compareTo("abd");因为c比d小,所以返还-1;按顺序拿分别从第一个字母进行比较,可以分出大小就不再继续往下比较;
char charAt(int index)//返回指定索引处的 char 值。
boolean contains(CharSequence s) //当且仅当此字符串包含指定的 char 值序列时,返回 true。
"abc".contains("bc"); //true
boolean endsWith(String suffix) //测试此字符串是否以指定的后缀结束。判断当前字符串是否以某个字符串结尾
"abc".endsWith("c"); //true
boolean equals(Object object) //比较两个字符串是否一样;不能使用“==”;equals方法没有调用compareTo方法:JDK13并没有调用compareTo方法
boolean equalsIgnoreCase(String anotherString) //将此 String 与另一个 String 比较,不考虑大小写
byte[] getBytes() //使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
byte[] b = "abcdef".getBytes();
int indexOf(String s)//判断某个字符串在当前字符串中第一次出现处的索引;
"abcdef".indexOf("cd"); // 2
boolean isEmpty();// 判断某个字符串是否为空;底层应该调用的是length()方法;
int length();//获得字符串长度
int lastIndexOf(String str);//获得当前字符串中某个子字符串最后一次出现的索引(下标)
"abcdeftr".lastIndexOf("de"); //3
String replace(CharSequence target, CharSequence replacement) //使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串。
"abcdefg".replace("de","xx"); //abcxxfg
String[] split(String regex) //根据给定正则表达式的匹配拆分此字符串。
"2020-03-05".split("-"); //以“-”进行拆分,并且返回一个String数组;
boolean startsWith(String prefix, int toffset) //测试此字符串从指定索引开始的子字符串是否以指定前缀开始
String substring(int beginIndex) //返回一个新的字符串,它是此字符串的一个子字符串。
String substring(int beginIndex, int endIndex) //返回一个新字符串,它是此字符串的一个子字符串。
"abcdefg".substring(2); //cdefg
char[] toCharArray() //将此字符串转换为一个新的字符数组。
String toLowerCase() //使用默认语言环境的规则将此 String 中的所有字符都转换为小写。
SString toUpperCase() //使用默认语言环境的规则将此 String 中的所有字符都转换为大写
String trim() //返回字符串的副本,忽略前导空白和尾部空白
String类中唯一的一个static静态方法valueOf()
static String valueOf(Object object);
//可以把所有类型的值转换成字符串;
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
思考:我们在实际开发中如果需要进行字符串频繁拼接会有什么问题:
因为java中的字符串是不可变的每一次拼接都会生成新的对象。这样
会占据大量方法区内存;造成空间浪费;
String s = “abc”;
s += “hello”;
以上的两行代码就在方法区生成三个对象内存空 间:“abc”、“hello”、“abchello”
如果需要进行字符串拼接:优先使用java.lang.StringBuffer类、java.lang.StringBuiler类
/*
* 字符串普通拼接与字符缓冲区对象拼接区别在于:
* 1、String类和StringBuffer类字符串对象都是存储在一个char[]数组中,String类定义的char[]数组是final关键字修饰的,而
* StingBuffer类底层的char[]数组是默认修饰符;所以String类的char数组是不可以改变(不可以扩容),而StringBuffer类底层
* 的char数组是可以改变的(改变其指向的char数组内存地址指向新的一个char数组,扩容);
* */
//创建一个初始容量16的char[] 数组(字符缓冲区对象)
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("a");
stringBuffer.append('b');
stringBuffer.append(true);
stringBuffer.append(10);
stringBuffer.append(3.14);
//toString()方法可以省略不写,因为系统会默认调用,可以不用手动写出;
System.out.println(stringBuffer.toString()); //abtrue103.14
如何优化StringBuffer的性能:
* 在创建StringBuffer对象的时候尽可能给定一个初始容量,
* 最好减少其底层数组扩容次数。预估一下给定初始化容量;
* new StringBuffer(int capacity)//构造一个不带字符,但具有指定初始容量的字符串缓冲区。
StringBuffer与StringBuilder的区别:
* StringBuilder的方法有synchronized修饰的,是多线程环境安全的;
* 而StringBuffer在多线程环境下是不安全的