学习目标:
Java 在大三上已经学过一学期的面向对象,所以打算在一星期把面向对象复习完成。
学习内容:
字符串
学习时间:
下午 6 点-下午9 点
学习产出:
字符串原理
扩展底层原理1:字符串存储的内存原理
直接赋值会复用字符串常量池中的
new出来不会复用,而是开辟一个新的空间
扩展底层原理2:==号比较的到底是什么?
基本数据类型比较数据值
引用数据类型比较地址值
扩展底层原理3:字符串拼接的底层原理
如果没有变量参与,都是字符串直接相加,编译之后就是拼接之后的结果,会复用串池中的字符串
如果有变量参与,会创建新的字符串,浪费内存
扩展底层原理4:StringBuilder提高效率原理图
所有要拼接的内容都会往StringBuilder中放,不会创建很多无用的空间,节约内存
扩展底层原理5:StringBuilder源码分析
默认创建一个长度为16 的字节数组
添加的内容长度小于16,直接存
添加的内容大于16会扩容(原来的容量2+2)
如果扩容之后还不够,以实际长度为准
练习:转换罗马数字
键盘录入一个字符串
要求1:长度为小于等于9
要求2:只能是数字
将内容变成罗马数字
注意点:罗马数字里面没有0的,如果键盘输入0,可变成“”(长度为0 的字符串)
解法一:
import java.util.Scanner;
public class Demo1 {
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
StringBuilder sb=new StringBuilder();
String num;
while (true) {
num=scan.next();
boolean flag=checkStr(num);
if (flag){
break;
}else {
System.out.println("字符串不符合规则");
continue;
}
}
for (int i = 0; i < num.length(); i++) {
char c=num.charAt(i);
int number=c-48;
sb.append(changeLunMa(number));
}
System.out.println(sb);
}
public static String changeLunMa(int number){
String [] arr={"","I","II","III","IV","V","VI","VII","VIII","IX"};
return arr[number];
}
public static boolean checkStr(String num){
if(num.length()>9){
return false;
}
for (int i = 0; i < num.length(); i++) {
char c=num.charAt(i);
if(c>'9'||c<'0'){
return false;
}
}
return true;
}
}
解法二:
import java.util.Scanner;
public class Demo2 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
StringBuilder sb = new StringBuilder();
String num;
while (true) {
num = scan.next();
boolean flag = checkStr(num);
if (flag) {
break;
} else {
System.out.println("字符串不符合规则");
continue;
}
}
for (int i = 0; i < num.length(); i++) {
char c = num.charAt(i);
//int number = c - 48;
sb.append(changeLunMa(c));
}
System.out.println(sb);
}
public static String changeLunMa(int number) {
String str=switch (number){ //jdk12用法
case '0'->"";
case '1'->"I";
case '2'->"II";
case '3'->"III";
case '4'->"IV";
case '5'->"V";
case '6'->"VI";
case '7'->"VII";
case '8'->"VIII";
case '9'->"IX";
default ->"";
};
return str;
}
public static boolean checkStr(String num) {
if (num.length() > 9) {
return false;
}
for (int i = 0; i < num.length(); i++) {
char c = num.charAt(i);
if (c > '9' || c < '0') {
return false;
}
}
return true;
}
}
练习:调整字符串
给定两个字符串,A和B
A的旋转操作就是将A最左边的字符移动到最右边
例如:若A=‘abcde’,在移动一次之后结果就是‘bcdea’
如果在若干次调整操作以后,A能变成B,那么返回True
若不能匹配成功,则返回false
解法一:
public class Dome3 {
public static void main(String[] args) {
String strA="abcde";
String strB="cdeab";
System.out.println(check(strA,strB));
}
public static boolean check(String strA,String strB){
for (int i = 0; i < strA.length(); i++) {
strA=rotate(strA);
if(strB.equals(strA)){
return true;
}
}
return false;
}
//x旋转字符串
public static String rotate(String str){
//套路
//如果我们看到要修改字符串的内容
//可以有两种办法:
//1.用subString进行截取,把左边的字符截取出来拼接到右侧去
//2.可以把字符串变成一个字符数组,然后调整字符数组里面数据,最后把字符数组变成字符串
char c=str.charAt(0);
String end=str.substring(1);
return end+c;
}
}
解法二:
public class Demo4 {
public static void main(String[] args) {
String strA="abcde";
String strB="cdeab";
System.out.println(check(strA,strB));
}
public static boolean check(String strA,String strB){
for (int i = 0; i < strA.length(); i++) {
strA=rotate(strA);
if(strB.equals(strA)){
return true;
}
}
return false;
}
//x旋转字符串
public static String rotate(String str){
//套路
//如果我们看到要修改字符串的内容
//可以有两种办法:
//1.用subString进行截取,把左边的字符截取出来拼接到右侧去
//2.可以把字符串变成一个字符数组,然后调整字符数组里面数据,最后把字符数组变成字符串
//"ABC"--->['A','B','C']
char[] arr=str.toCharArray();
char first=arr[0];
for (int i = 1; i < arr.length; i++) {
arr[i-1]=arr[i];
}
//把原来0索引上的字符放到最后
arr[arr.length-1]=first;
String result=new String(arr);
return result;
}
}
练习:键盘输入任意字符串,打乱里面的内容
import java.util.Random;
import java.util.Scanner;
public class Demo5 {
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
String str=scan.next();
char[] c=str.toCharArray();
char m = 0;
for (int i = 0; i < c.length; i++) {
m=c[i];
Random random = new Random();
int num=random.nextInt(0,c.length);
c[i]=c[num];
c[num]=m;
}
String result=new String(c);
System.out.println(result);
}
}
运行结果
dgnr
gndr
到此字符串的学习告一段落,期待下一个征程。
用良知驾驭我们之所学,
而不因所学蒙蔽了良知。