目录
5.简化StringBuilder的书写:StringJoiner类的使用
9.练习: 把一个字符串的第一位移动到最后一位,看看这个重复过程能不能与另一个字符串的值相等
10.练习:生成验证码,四位字母(不分大小写),一位数字(随机位置)
1.如何截取字符串?使用subString方法!
案例:截取电话号码中间四位
public class demo109 {
public static void main(String[] args) {
String phoneNumber = "19567417827";
String str = " **** ";
phoneNumber = phoneNumber.substring(0, 3) + str + phoneNumber.substring(7);
System.out.println(phoneNumber);
}
}
输出:
2.如何替换字符串中的内容?使用replace方法!
案例:敏感词替换
public class demo1010 {
public static void main(String[] args) {
String talk = "你TMD,CNM,TNND,MLGB";
String[] arr = {"TMD", "NMD", "CNM", "TNND", "MLGB", "SB"};
for (int i = 0; i < arr.length; i++) {
talk = talk.replace(arr[i], "***");
}
System.out.println("把所有敏感词都替换掉后的内容为\n"+talk);
}
}
输出:
、
3.可变的字符串:StringBuilder类
StringBuilder的使用:可以看成是一个容器,创建之后里面的内容可变,不会像String的变化那样产生新的对象,可用于大量添加字符到String 或者 字符串反转之时。
public class demo1011 {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("abc");//这里面也可以不放字符串
System.out.println("使用length方法得到StringBuilder长度:"+sb.length());
sb.reverse();
System.out.println("使用reverse方法反转StringBuilder:"+sb);//直接输出和String一样会输出属性值!
sb.reverse();
//下列数据类型都可以加
sb.append("d").append('e').append(12345.666);
System.out.println("使用append方法添加字符或者字符串:"+sb);
String s = sb.toString();
System.out.println("使用toString方法将StringBuilder转变为String:"+s);
}
}
输出:
4. 链式编程:快捷方便的编程方法。
在调用方法的时候,不需要用变量接受结果,可以继续调用其他方法。
public class demo1012 {
public static void main(String[] args) {
System.out.println(getString().substring(1).replace("A", "B"));
}
public static String getString() {
System.out.println("请输入一个字符串");
String str = new Scanner(System.in).next();
return str;
}
}
输出结果:此处输出的是截取字符串从下标1到最后截取下来,再把该所有A转化为B后的字符串
5.简化StringBuilder的书写:StringJoiner类的使用
案例:把数组转化为字符串的格式输出
StringBuilder案例:需要手动添加分隔符号,前缀后缀
public class demo1013 {
public static void main(String[] args) {
int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9};
StringBuilder sb = new StringBuilder();
sb.append("[");
for (int i = 0; i < arr.length - 1; i++) {
sb.append(arr[i]);
sb.append(',');
}
sb.append(arr[arr.length - 1]);
sb.append(']');
System.out.println(sb);
}
}
Stringjoiner案例:自动添加 分隔符号,前缀后缀
public class demo1014 {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9};
StringJoiner sj = new StringJoiner(", ");//分隔符号
for (int i = 0; i < arr.length; i++) {
sj.add(arr[i] + "");
}
System.out.println("只加分隔符号的StringJoiner:"+sj);
StringJoiner sj1 = new StringJoiner(", ", "[", "]");//分隔符号,开始符号,结束符号。
for (int i = 0; i < arr.length; i++) {
sj1.add(arr[i] + "");
}
System.out.println("加了分隔符号,开始符号,结束符号的StringJoiner:"+sj1);
String str = sj1.toString();
System.out.println("使用toStirng方法把StringJoiner转换为支付串"+str);
System.out.println("使用length方法得到StringJoiner的长度"+sj1.length());
}
}
输出结果:
6.字符串拼接的内存原理
下面在代码中进行说明
public class demo1015 {
public static void main(String[] args) {
//1.等号右边没有变量参与的情况
//触发字符串优化机制,在编译过后就已经是最终的结果了,相当于String s=“abc”,故该语句在串池中创建一个有“abc”的内存空间
String s = "a" + "b" + "c";
//等号右边有变量参与的情况
//在串池中开辟“a”的空间
String s1 = "a";
//在堆内存中(不是串池)new一个StringBuilder对象,调用append方法合并a与b,再调用toString方法转变回字符串(字符串也在堆内存中),
//相当于 String s2=new StringBuilder().append(s1).append("b").toString;
//ctrl+N右上角选择allPlaces搜索StringBuilder对象,ctrl+F12搜索toString方法查看源码
String s2 = s1 + "b";
//在堆内存中new一个StringBuilder对象,内容为”abc“
String s3 = s2 + "c";
//在JDK8以前,这行代码要在内存中创建4个对象(ab与abc,StringBuilder与String),在JDK8及以后,只要创建一个字符串对象(abc)
String s4 = s1 + s2 + s3;
//结论:在字符串运算中使用+号拼接比较占内存(会创建新的对象)
}
}
7.StringBuilder的内存原理
默认容量为16,内部存放ASCII码,最大长度是Int的最大值。超过这个容量时,会扩容:老容量*2+2=34。超过34后则以实际字符串长度为准。
案例代码:
public class demo1016 {
public static void main(String[] args) {
System.out.println("创建StringBuilder");
StringBuilder sb = new StringBuilder();
System.out.println("输出初始状态下StringBuilder的容量:"+sb.capacity());
System.out.println("输出初始状态下StringBuilder的长度:"+sb.length());
sb.append("abc");
System.out.println("输出加入长度为3的字符串后StringBuilder的容量:"+sb.capacity());
System.out.println("输出加入长度为3的字符串后StringBuilder的长度:"+sb.length());//输出StringBuilder的长度
sb.append("defghijkmnlopqrstuvwxyz");
System.out.println("输出再次加入长度为23的字符串后(此时StringBuilder长度为26,超过16)StringBuilder的容量:"+sb.capacity());
System.out.println("输出再次加入长度为23的字符串后(此时StringBuilder长度为26,超过16)StringBuilder的长度:"+sb.length());
sb.append("0123456789");
System.out.println("输出再次加入长度为10的字符串后(此时StringBuilder长度为36,超过34)StringBuilder的容量:"+sb.capacity());
System.out.println("输出再次加入长度为10的字符串后(此时StringBuilder长度为36,超过34)StringBuilder的长度:"+sb.length());
System.out.println("创建第二个StringBuilder");
StringBuilder sb1 = new StringBuilder();
sb1.append("abcdefghijkmnlopqrstuvwxyz0123456789");
System.out.println("输出直接加入长度为36的字符串后(此时StringBuilder长度为36,超过34)StringBuilder的容量:"+sb1.capacity());//输出StringBuilder的容量
System.out.println("输出直接加入长度为36的字符串后(此时StringBuilder长度为36,超过34)StringBuilder的长度:"+sb1.length());//输出StringBuilder的长度
sb1.append("abcdefghijkmnlopqrstuvwxyz0123456789");
System.out.println("输出再次加入长度为36的字符串后(此时StringBuilder长度为72,超过36)StringBuilder的容量:"+sb1.capacity());//输出StringBuilder的容量
System.out.println("输出再次加入长度为36的字符串后(此时StringBuilder长度为72,超过36)StringBuilder的长度:"+sb1.length());//输出StringBuilder的长度
}
}
输出:
8.练习:键盘录入字符串,输出罗马数字
public class demo1017 {
public static void main(String[] args) {
String str;
Scanner scanner = new Scanner(System.in);
boolean flag;
//选中代码ctrl+alt+t生成while循环
while (true) {
flag = true;
System.out.println("请输入字符串");
str = scanner.next();
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) > '9' || str.charAt(i) < '0') {
System.out.println("字符串中只能存在数字!");
flag = false;
break;
}
}
if (flag)//别写成flag=true了,老师刚讲就这么写了,总以为我不会这么写。。。。。。
break;
}
char[] chars = {' ', 'Ⅰ', 'Ⅱ', 'Ⅲ', 'Ⅳ', 'Ⅴ', 'Ⅵ', 'Ⅶ', 'Ⅷ', 'Ⅸ'};
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
sb.append(chars[str.charAt(i) - '0']);
}
System.out.println(sb);
}
}
输出:
9.练习: 把一个字符串的第一位移动到最后一位,看看这个重复过程能不能与另一个字符串的值相等
在这一题中使用String的subString方法做会更方便。
//StringBuffer版,复杂了
public class demo1018 {
public static void main(String[] args) {
String A="abcde";
String B="eabcd";
StringBuilder sbA=new StringBuilder(A);
if (A.length()==B.length()) {
for (int i = 0; i < A.length(); i++) {
sbA=change(sbA);
if (sbA.toString().equals(B)){
System.out.println("可");
return;
}
}
}
System.out.println("否");
}
public static StringBuilder change(StringBuilder sb1){
StringBuilder sb2=new StringBuilder();
//这里可以用到subString方法,不用一个一个去加
sb2.append(sb1.substring(1));
sb2.append(sb1.charAt(0));
return sb2;
}
}
//String版
public class demo1019 {
public static void main(String[] args) {
String A = "abcde";
String B = "eabcd";
if (A.length() == B.length()) {
for (int i = 0; i < A.length(); i++) {
A = change(A);
if (A.equals(B)) {
System.out.println("可");
return;
}
}
}
System.out.println("否");
}
public static String change(String s) {
//把String类型转化为char[]类型可以用toCharArray方法
String end = s.substring(1);
char start = s.charAt(0);
return end + start;
}
}
10.练习:生成验证码,四位字母(不分大小写),一位数字(随机位置)
// 我的思路是先把数字放在char[]当中,再从零开始把字母一个一个加入到数组中,但是每加一个要判断一下
// 老师的思路是最后加入数字,再用随机数替换最后一个数字与前面的字母的位置就可以了
public class demo1020 {
public static void main(String[] args) {
char[] arr = new char[52];
for (int i = 0; i < 26; i++) {
arr[i]=(char)('a'+i);
}
for (int i = 0; i < 26; i++) {
arr[i+26]=(char)('A'+i);
}
char[] verification =new char[5];
Random random=new Random();
for (int i = 0; i < 4; i++) {
verification[i]=arr[random.nextInt(arr.length)];
}
verification[4]=(char)(random.nextInt(10)+'0');
System.out.println(verification);
int r=random.nextInt(4);
char temp=verification[4];
verification[4]=verification[r];
verification[r]=temp;
System.out.println(verification);
}
}
输出:第一个为数字未变化的结果,第二个为数字随机变化后的结果。