目录
1 常用方法
1.1 字符串构造
1.2 字符串包含的成员
1.3 String 对象的比较
1.4 字符串查找
1.5 转化
1.5.1 数值和字符串转化
1.5.2 大小写转化
1.5.3 字符串转数组
1.5.4 格式化
1.6 字符串替换
1.7 字符串拆分
1.8 字符串截取
1.9 其他操作方法
1.10 字符串的不可变性
1.11 字符串修改
2 StringBuilder 和 StringBuffer
2.1 StringBuilder 和 StringBuffer 的区别
2.2 StringBuilder、StringBuffer 和 String 比较
3 试题
1 常用方法
1.1 字符串构造
String 是字符串类型
String 类提供的构造方式非常多,常用的就以下三种:
① 使用常量串构造
String s1 = "hello bit";
System.out.println(s1);
② 直接 newString 对象
String s2 = new String("hello bit");
System.out.println(s1);
③ 使用字符数组进行构造
char[] array = {'h','e','l','l','o','b','i','t'};
String s3 = new String(array);
System.out.println(s1);
其它构造方法
从0位置开始偏移1个输出 a
从0位置开始偏移2个输出 ab
从1位置开始偏移2个输出 bc
1.2 字符串包含的成员
① 注意:String 是引用类型,内部并不存储字符串本身,在 String 类的实现源码中,String 类实例变量如下:
System.out.println(s1.length());
// 获取字符串长度
// 打印"hello"字符串(String对象)的长度也可以直接某一字符串. length()
System.out.println("hello".length());
结果:5
System.out.println(s1.isEmpty());
// 如果字符串长度为0,返回true,否则返回 false
② 在 Java 中 “ ” 引起来的是 String 类型对象
1.3 String 对象的比较
① == 比较(两个引用变量比较的是地址)
② 比较内容(boolean equals(Object anObject))
③ 比较大小(int compareTo(String s))
④ 忽略大小写比较大小(int compareToIgnoreCase(String str))
1.4 字符串查找
① char charAt(int index) (通过下标返回字符)
返回 index 位置上字符,如果 index 为负数或者越界,抛出 IndexOutOfBoundsException 异常
一个一个字符串进行打印
② int indexOf(int ch) (通过字符返回下标)
返回 ch 第一次出现的位置,没有返回-1
当出现两个相同字符串时默认从头到后(第一个字符串出现的位置)
③ int indexOf(int ch, int fromIndex) (从指定位置开始查找)
从 fromIndex 位置开始找 ch 第一次出现的位置,没有返回-1
从3位置开始找,打印结果为:3
从指定位置查找字符串出现的位置
从3位置开始找,打印结果为:5
④ int lastIndexOf(int ch) (通过下标倒着找字符)
从后往前找,返回 ch 第一次出现的位置,没有返回-1
结果:5
⑤ int lastIndexOf(int ch, int fromIndex) (从指定位置倒着往回找)
从 fromIndex 位置开始找,从后往前找 ch 第一次出现的位置,没有返 回-1
从4位置开始倒着往回找,结果为:2
1.5 转化
1.5.1 数值和字符串转化
ValueOf 中不管传任何数据都会变成字符串
也可以字符串转数字
1.5.2 大小写转化
① toUpperCase (小写变大写,原来大写的不动)
转变大小写需要进行接收,是一个新对象
未接收则是原来的对象
② toLowerCase (大写变小写,原来小写的不动)
1.5.3 字符串转数组
数组转字符串
1.5.4 格式化
此处 %d 相当于一个占位符
1.6 字符串替换
replace(有两种)
两个 replace 里面的参数不一样,一个两个都是 char 类型,还有一个两个都是 charSequence
String 类在定义时实现了 charSequence 接口,意味着对于 charSequence 接口本身来说能接收String 类型数据
对 String 本身修改都是产生新的对象的(字符串的不可变性)
另外两个与 replace 有关的
① replaceFrist (只对第一次出现的进行修改)
② replaceAll (替换所有指定内容)
1.7 字符串拆分
以空格为分割拆分
以空格分开最多分两组
特殊情况
①
修改后
②
③
也可以进行两次分割(在第一次分割基础上进行第二次分割)
注意
1. 字符“.”,“|”,“*”,“+”都得加上转义字符,前面加上 “\\”
2. 而如果是 “\\” ,那么就得写成 “\\\\”
3. 如果一个字符串中有多个分隔符,可以用“|”作为连字符
1.8 字符串截取
1.9 其他操作方法
1.10 字符串的不可变性
String 类不能修改的主要原因是:String 类功能是私有的
String 是一种不可变对象,字符串中的内容是不可改变,字符串不可被修改,是因为:
① String 类在设计时就是不可改变的,String 类实现描述中已经说明了
以下来自 JDK1.8 中 String 类的部分实现:
String 类中的字符实际保存在内部维护的 value 字符数组中,该图还可以看出:
1. String 类被 final 修饰,表明该类不能被继承
2. value 被修饰被 final 修饰,表明 value 自身的值不能改变,即不能引用其它字符数组,但是其引用空间中的内容可以修改
② 所有涉及到可能修改字符串内容的操作都是创建一个新对象,改变的是新对象
纠正:字符串不可变是因为其内部保存字符的数组被final修饰了,因此不能改变,这种说法是错误的,不是因为 String 类自身,或者其内部 value 被 final 修饰而不能被修改
final 修饰类表明该类不想被继承,final 修饰引用类型表明该引用变量不能引用其他对象,但是其引用对象中的内容是可以修改的
为什么 String 要设计成不可变的?(不可变对象的好处是什么?)
1. 方便实现字符串对象池,如果 String 可变,那么对象池就需要考虑写时拷贝的问题了
2. 不可变对象是线程安全的
3. 不可变对象更方便缓存 hash code, 作为 key 时可以更高效的保存到 HashMap 中
那如果想要修改字符串中内容,该如何操作呢?
1.11 字符串修改
注意:尽量避免直接对 String 类型对象进行修改,因为 String 类是不能修改的,所有的修改都会创建新对象,效率非常低下
如果要修改建议尽量使用 StringBuffer 或者 StringBuilder
String、StringBuffer、StringBuilder 对 String 类型对象进行修改,由于 String 类不能修改,所有的修改都会创建新对象,每次返回的对象都不一样,不断地创建对象销毁对象,效率非常低下,而 StringBuffer、StringBuilde 都在 append 拼接后指向同一个对象
String、StringBuffer、StringBuilder 对 String 类型对象进行修改前后之间的时间对比
2 StringBuilder 和 StringBuffer
由于 String 不可更改特性,为了方便字符串的修改, Java 中又提供 StringBuilder 和 StringBuffer 类,这两个类大部分功能是相同的
2.1 StringBuilder 和 StringBuffer 的区别
StringBuffer 的 append 方法
StringBuilder 的 append 方法
StringBuilder 和 StringBuffer 中 append 内容没什么区别,都是返回 this,区别在于方法旁边的关键字
线程安全类似于一间厕所有人进去后就上了锁,即同一时间只有一个线程可以执行此方法
每次开锁和上锁都需要耗费资源,StringBuffer 是线程安全的,也意味着在多线程情况下虽然安全,但是效率很低,频繁的开锁上锁对资源是消耗的
2.2 StringBuilder、StringBuffer 和 String 比较
StringBuilder 和 StringBuffer 这两个类包含了一些 String 没有的方法,它的功能进一步扩大
StringBuff append(String str)
在尾部追加,相当于 String的+=,可以追加(追加:即尾插):boolean、char、char[]、 double、float、int、long、Object、String、StringBuff 的变量
StringBuff insert(int offset, String str)
在 offset 位置插入:八种基类类型 & String类型 & Object类型数据
public class StringBufferInsertExample {
public static void main(String[] args) {
StringBuffer buffer = new StringBuffer("Hello World!");
buffer.insert(6, "Beautiful ");
System.out.println(buffer.toString()); // 输出: Hello Beautiful World!
}
}
StringBuffer deleteCharAt(int index)
删除index位置字符
StringBuffer delete(int start, int end)
删除[start, end)区间内的字符
StringBuffer replace(int start, int end, String str)
将[start, end)位置的字符替换为str
StringBuffer reverse()
反转字符串:对字符串进行逆置
以 String 方法返回的方法
String 和 StringBuilder、StringBuffer 类不能直接转换,要想互相转换,可以采用如下原则:
String 变为 StringBuilder 或 StringBuffer:利用 StringBuilder 的构造方法或 append() 方法
StringBuilder 变为String:调用 toString() 方法
补充
String、StringBuffer、StringBuilder 的区别
String 的内容不可修改,StringBuffer 与 StringBuilder 的内容可以修改,包含的方法也不一样
StringBuffer 与 StringBuilder 大部分功能是相似的
StringBuffer 采用同步处理,属于线程安全操作
StringBuilder 未采用同步处理,属于线程不安全操作
3 试题
① 第一个只出现一次的字符
② 最后一个单词的长度
③ 检测字符串是否为回文
④ 字符串相加
⑤ 字符串转整形数字
方法一:使用Integer.parseInt()方法:
方法二:定义了一个 stringToInt 方法,它尝试将输入的字符串转换为整数。如果字符串不是一个有效的整数表示,则返回0。代码还处理了溢出情况,确保返回的整数在 Java 的 Integer 类型的范围内
public class StringToInteger {
public static void main(String[] args) {
String str = "1234";
int num = stringToInt(str);
System.out.println("转换后的整数为: " + num);
}
public static int stringToInt(String str) {
if (str == null) {
return 0;
}
int res = 0;
boolean isPositive = true;
for (int i = 0; i < str.length(); i++) {
if (i == 0 && (str.charAt(i) == '-' || str.charAt(i) == '+')) {
isPositive = str.charAt(i) == '+' ? true : false;
continue;
}
if (str.charAt(i) < '0' || str.charAt(i) > '9') {
return 0;
}
res = res * 10 + (str.charAt(i) - '0');
if (res > Integer.MAX_VALUE) {
return isPositive ? Integer.MAX_VALUE : Integer.MIN_VALUE;
}
}
return isPositive ? res : -res;
}
}