一、String 类
String类的特点 :
①Java 程序中所有双引号字符串 , 都是 String 类的对象
例如:String passWord ="12345"
②字符串在创建之后 , 其内容不可更改,如果想要更改, 只能使用新的对象, 做替换
例:String s="abc" //创建一个字符串
s="bfg" //这个地方相当于重新创建一个字符串覆盖原有的
即s = new String("bfg")
System.out.println(s); //打印输出的结果是bfg
③字符串虽然不可改变 , 但是可以被共享
字符串常量池: 当我们使用双引号创建字符串对象时, 会检查常量池中是否存在
该数据,不存在 ,创建 ,存在 ,复用。
String 类的常见构造方法
// public String() : 创建一个空白字符串, 里面不含任何内容
String s1 = new String();
System.out.println(s1);
// public String(char[] chs) : 根据传入的字符数组, 创建字符串对象
char[] chs = {'a','b','c'};
String s2 = new String(chs);
System.out.println(s2);
// public String(String original) : 根据传入的字符串, 来创建字符串对象
String s3 = new String("abc");
System.out.println(s3);
String 类的常见面试题
1.下面这段代码输出的结果
string a1 = "abc";
String a2 = "abc"
System.out.println(a1==a2);
答案:true
解析:在创建第一个字符a1时,系统会去字符串常量池中查找是否有相同的字符串,发现没有,在字符串常量池中会生成一个“abc”,在创建第二个字符串a2时,系统会去字符串常量池中再次查找是否有相同的字符串,发现有,就直接赋值给a2,a1和a2指向的是同一个字符。串。
2.下面这段代码输出的结果
string a1 = "abc";
String a2 = new String("abc")
System.out.println(a1==a2);
答案:false
根据Sting的创建方式创建a1时直接去常量池找,发现没有,在常量池中创建“abc”字符串,a1指向常量池中的字符串,创建a2时,因为有new所以在堆空间中开辟一块String空间,然后去常量池中查找字符串,发现有字符串“abc”,将字符串拷贝一份存入创建的String空间,之后地址赋值给a2,这样a1指向的是常量池,a2指向的是字符空间,a1和a2指向不同,所以返回值是false.
若想将a1和a2进行比较需要通过equals,equalslgnoreCase方法:
System.out.println(a1.equals(a2)); // true,完全一样才是true,否则为false
System.out.println(a1.equalslgnoreCase(a2)); // true,忽略大小写的比较
3.下面这段代码输出的结果
string a1 = "abc";
String a2 = “ab”
String a3 = a2 + “c”
System.out.println(a1==a3);
答案:false
根据双引号创建String的方式,先去常量池中查找是否有对应的字符串,没有创建,a1和a2是相同的道理,创建a3时同样先去常量池中查找字符“c”没有创建,a2和“c”进行+号拼接的时候,Java会自动new 一个StringBuilder进行拼接,并调用toString的方法返回一个string空间,并将地址赋值给a3,所以a1和a3所记录的地址是不一样的,所以返回结果是false。
3.下面这段代码输出的结果
string a1 = "abc";
String a2 = "a" + "b" + "c"
System.out.println(a1==a2);
答案:true
解析:Java有字符串优化机制,在产量进行拼接时,在转换成自解码文件时,就已经完成了字符串拼接,自解码文件中a2="abc"的,根据String的创建方式可知a1和a2记录的是同一个地址。
案例:
需求:一直正确的用户名和密码,请用程序实现模拟用户登录,总共三次机会,登录之后,给出相应的提示。
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 1. 定义两个字符串类型变量, 模拟已经存在的用户名和密码
String username = "admin";
String password = "123456";
for (int i = 1; i <= 3; i++) {
// 2. 键盘录入用户输入的用户名, 密码
System.out.println("请输入用户名:");
String inputUsername = sc.nextLine();
System.out.println("请输入密码:");
String inputPassword = sc.nextLine();
// 3. 比对
if (inputUsername.equals(username) && inputPassword.equals(password)) {
System.out.println("登录成功!");
break;
} else {
if (i == 3) {
System.out.println("明儿再来吧~");
} else {
System.out.println("登录失败, 您还剩余" + (3 - i) + "次机会");
}
}
}
}
String 字符串的遍历
1.public char[] toCharAray () 将字符串转换成字符数组
String s = "hallow";
char[] chars = s.toCharArray(); //转化成字符数组
for (int i = 0; i < chars.length; i++) { //对数组进行遍历
System.out.println(chars[i]);
}
2.public char chatAt(int index)根据索引找字符
public int length() 返回字符串的长度
String s = "hallow";
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
System.out.println(c);
}
两种遍历方式,第一种的方式效率更高,因为第二种方法中length()是方法,每次循环走到这里都需要进行进栈和出栈的操作,遍历多少次就要进出多少次,而第一种只有在将字符串转换成字符数组的时候调用了一次方法。进栈出栈一次,数组的length是属性,所以效率更高。
案例:
需求 : 键盘录入一个字符串,统计该字符串中大写字母字符,小写字母字符,数字字符出现的次数
(不考虑其他字符)
例如 : aAb3&c2B*4CD1
小写字母 : 3个 大写字母 : 4个 数字字母 : 4个
Scanner sc = new Scanner(System.in); // 1. 键盘录入一个字符串
System.out.println("请输入:");
String content = sc.nextLine();
int smallCount = 0; // 2. 定义三份计数器变量, 用于统计操作
int bigCount = 0;
int numCount = 0;
char[] chars = content.toCharArray(); // 3.将字符串转化成字符数组
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
// 4. 在遍历的过程中, 加入if判断, 看字符属于哪一种类别
if (c >= 'a' && c <= 'z') {
// 5. 对应的计数器变量自增
smallCount++;
} else if (c >= 'A' && c <= 'Z') {
bigCount++;
} else if (c >= '0' && c <= '9') {
numCount++;
}
}
String 字符串的截取方法
1.public String substring(int beginIndex,int endlndex) //包含头不包含尾,返回值是截取的字符串
2.public String substring(int beginIndex) //截取到末尾
案例:
需求 :以字符串的形式从键盘接受一个手机号,将中间四位号码屏蔽
最终结果为:185****1234
// 1. 键盘录入字符串
Scanner sc = new Scanner(System.in);
System.out.println("请输入手机号:");
String tel = sc.nextLine();
// 2. 截取前三位
String start = tel.substring(0, 3);
// 3. 截取后四位
String end = tel.substring(7);
// 4. 前三位 + "****" + 后四位
System.out.println(start + "****" + end);
String 字符串的替换方法
public String replace(old,new) //用new替换掉old,返回值是替换之后的结果。
案例:
需求:键盘录入一个 字符串,如果字符串中包含(TMD), 则使用 *** 替换
Scanner sc = new Scanner(System.in);
System.out.println("请输入:");
String content = sc.nextLine();
content = content.replace("TMD","***");
System.out.println(content);
String 字符串的切割方法
public String[] split(String regex)
//根据传入的字符串作为规则进行切割,将切割后的内容存入字符串数组中,并将字符串数组返回
二、StringBuilder类
StringBuilder 是字符串的缓冲区,即字符串的一个容器,它是一种可变的字符序列,它的引入是为了提高字符串的操作效率
StringBuilder构造方法
public StringBuilder() //创建一个空的字符串缓冲区
public StringBuilder(String str) //创建一个字符串缓冲区,并初始化好指定的参数内容
StringBuilder 常用方法
public StringBuilder append(任意类型) //添加数据,并返回对象本身
public StringBuilder reverse() //反转容器中的内容
public int length() //返回长度(字符出现的个数)
public String toString() // 通过toString()就可以实现把StringBuilder 转换为String
案例:
需求: 键盘接受一个字符串,程序判断出该字符串是否是对称字符串(回文字符串),并在控制台打印是或不是
对称字符串: 123321、111
非对称字符串: 123123
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个对称字符串: ");
String content = sc.nextLine();
// 将String转换为StringBuilder, 为了调用内部反转的方法
StringBuilder sb = new StringBuilder(content);
sb.reverse();
// 判断反转后的内容, 和原数据是否相同
// content : String类型
// sb : StringBuilder类型
if (content.equals(sb.toString())) {
System.out.println("是对称字符串");
} else {
System.out.println("不是对称字符串");
}
案例:
需求:定义一个方法,把int数组中的数据按照指定的格式拼接成一个字符串返回
调用该方法,并在控制台输出结果
例如:数组为int[] arr = {1,2,3};输出结果为:[1,2,3]
public static String arrayToString(int[] arr) {
// 1. 创建StringBuilder, 准备进行拼接
StringBuilder sb = new StringBuilder("[");
// 2. 遍历数组, 获取内部元素
for (int i = 0; i < arr.length - 1; i++) {
// 3. 将获取到的元素, 拼接到字符串缓冲区
sb.append(arr[i]).append(", ");
}
// 4. 特殊处理最后一个元素
sb.append(arr[arr.length - 1]).append("]");
return sb.toString();
}