String
- String是java定义好的类,定义在java.lang包中,所以使用时不需要导包
- 字符串不可改变,他们的值在创建后不能被更改。
1.创建字符串(String构造方法)
直接赋值和 构造方法new
直接赋值,比较直观
String s = "apple";
构造方法可以有几种选择,常用的有:
构造方法 | 说明 |
---|---|
public String() | 创建空白字符串,不含任何内容 |
public String(String original) | 根据传入的字符串,创建字符串对象 |
public String(char[] chs) | 根据字符数组,创建字符串对象 |
public String(byte[] chs) | 根据字节数组,创建字符串对象 |
// 可以获取一个空的字符串
String s1 = new String();
// 比较多余(不如直接赋值)
String s2 = new String("abc");
// 当要修改字符串时,可以先采用字符数组,再用构造方法将它转换
char[] chs ={'a','b','c'};
String s3 = =new String(chs);
直接赋值和new出来的字符串有什么不同的呢——内存上的不同
直接赋值,String 创建的字符串存储在公共池中。系统会检查,不存在,创建新的,存在,复用。
new 创建的字符串对象在堆内存上。
2.字符串的比较
在字符串比较中,会涉及到==与equals两种方式。
首先==是检查如果两个操作数的值是否相等,如果相等则条件为真。
基本数据类型比较的是 数据值,引用数据类型比较的是 地址值。
再比如:
String s1=new String("aaa");
String s2 = "aaa";
System.out.println(s1==s2); // 输出false
至于为什么,就需要看看我们前面说的String创建的几种方式。
直接赋值创建,字符串存储在公共池中;
new创建在堆内存中,两者存储的地址不一样,所以==输出false。
由此引入equals——比较字符串的值
方法 | 含义 |
---|---|
boolean equals(Object anObject) | 比较两个字符串的内容是否相等,参数为要比较的字符串 |
boolean equalsIgonreCase(Object anObject) | 忽略大小写,比较字符串 |
所以,通常情况下比较两个字符串是否相同用的都是equals方法!(一般只关心字符串的值是否相同)
3.字符串的连接
最常用的方法就是连接符 “+”
(当然也还有方法concat,string1.concat(string2);
)
因为字符串不能改变,所以每次拼接时都会产生一个新的对象,即s1与s2拼接产生一个新对象,这个新对象又去和s3进行拼接,依次类推。
所以:
在字符串需要多次拼接时,效率比较低下,且浪费空间(由此引入StringBuilder)
4.其他常用方法
更多方法可参见:https://www.runoob.com/java/java-string.html
方法 | 含义 |
---|---|
char charAt(int index) | 返回指定索引处的字符 |
int length() | 返回字符串长度 |
boolean isEmpty() | 判断字符串是否为空 |
String concat(String s) | 将指定的字符串参数连接到字符串上 |
String replace(char searchChar, char newChar) | 用 newChar 字符替换字符串中出现的所有 searchChar 字符 |
char[ ] toCharArray() | 将字符串转换为字符数组 |
String substring(int beginIndex, int endIndex) | 返回字符串的子字符串(截取),起始索引(包括)—结束索引(不包括) |
String substring(int beginIndex) | 从beginIndex截取到末尾索引 |
引:
从上述方法可以得到:如果需要改变字符串的值,可以采用变通的方法:
- 使用字符数组,
toCharArray()
,将字符串转化为字符数组处理 - 使用
substring
对字符串截取,再进行拼接
StringBuilder
1.背景
- 字符串创建后不能修改
- 字符串连接的情况,一般通过"+"符号来实现,但是这种方式的效率比较低,且每执行一次都会创建一个String对象,即耗时,又浪费空间
当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。
和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。
所以通常我们在拼接字符串(提高字符串的操作效率)和反转字符串(String无反转API方法)的时候会使用到
2.构造方法
方法 | 含义 |
---|---|
StringBuilder() | 空参构造函数 |
StringBuilder(String str) | 有参构造函数 |
3.常用方法
方法 | 含义 |
---|---|
StringBuilder append() | 添加数据(字符串连接),并返回对象本身 |
StringBuilder reverse() | 反转容器中的内容 |
int length() | 返回容器的长度 |
StringBuilder toString() | 将StringBuilder转换为String |
eg.
// 空参构造函数
StringBuilder sb1 = new StringBuilder();
// 有参构造函数
StringBuilder sb2 = new StringBuilder("abc")
sb2.append(1);
System.out.println(sb2); // abc1
sb2.reverse();
System.out.println(sb2); // 1cba
// 将 StringBuilder 转化为 String
String s = sb2.toString();
最后说一句,字符串的用法非常灵活,有时就会纠结使用String还是StringBuilder,或者考虑到底有什么方法可以使用,只能说熟能生巧,多看文档。
实例:开发验证码
(以一个小例子结束字符串的学习)
需求:
开发一个验证码,长度为5,由4位大写或者小写字母及1位数字组成,数字可以出现在任意位置
思路:
4个字母是随机的,所以可以新建一个字符数组或者字符集合,再从其中随机抽取4个,然后再添加一个数字。这样生成的字符串就是前4位是字母,后1位是数字。
最后再将最后一位的数字与前面的任意字母进行交换(可以采用随机索引)。
总结:Random类,List集合,StringBuilder类
代码:
public static String idCode()
{
// 新建一个集合,用来存放字符
ArrayList<Character> list = new ArrayList<>();
// 新建一个StringBuilder对象,用来存放验证码字符串
StringBuilder sb =new StringBuilder();
Random random = new Random();
// 将大小写 52 个字符添加到 list 中
for(int i=0;i<26;i++)
{
list.add((char) ('a'+i));
list.add((char)('A'+i));
}
// 四个字母,所以进行4次随机添加
for(int j=0;j<4;j++) {
// 获取随机索引,范围 0-size
int index = random.nextInt(list.size());
// 通过索引获得list集合中的字符
char chs = list.get(index);
// 添加到sb对象中
sb.append(chs);
}
// 再随机生成一个数字,添加到sb末尾
int num = random.nextInt(10);
sb.append(num);
/*
为了数字的随机位置,将末尾数字与前面的任意字符进行交换
*/
// 先将sb对象转换为字符数组
char[] chs = sb.toString().toCharArray();
/*
生成随机索引,并进行交换,(交换3段论)
*/
int index = random.nextInt(chs.length);
char tmp = chs[index];
chs[index] = chs[sb.length()-1];
chs[sb.length()-1] = tmp;
return new String(chs);
}
参考链接:
https://www.bilibili.com/video/BV17F411T7Ao?p=97
https://www.runoob.com/java/java-string.html