JavaSE(07) - API -String字符串
p 96 API和API帮助文档
p97 String 概述
java.lang.String类代表字符串, java程序中的所有字符串文字(例如"abc")都是此类的对象.
注意点 : 字符串的内容是不会发生改变的, 他的对象在创建后不能被更改.
p89 String的构造方法代码实现和内存分析
常用构造方法
- 直接赋值 : String name = "George";
- new关键字
//1. 空参构造 : 可以获得一个空白的字符串对象.
String s1 = new String();//""
//2. 在参数中传递一个字符串
String s2 new String ("abc");//abc
//3. 传递一个字符数组, 根据数组的内容再创建一个新的字符串对象
//应用场景: 修改字符串的内容. abc -> Qbc
//"abc" --> {'a','b','c'} --> {'Q','b','c'} --> "Qbc"
char[] chars = {'a', 'b', 'c'};
String s3 = new String(chars);
System.out.println(s3);//abc
/*传递一个字节数组,根据字节数组的内容再创建一个新的字节串对象
* 应用场景: 以后在网络当中传输信息其实都是字节信息,我们一般要把字节信息进行转换,转成字符串,就要用到这个构造.*/
byte[] bytes = {97, 98, 99,100};
String s4 = new String(bytes);
System.out.println(s4);//abcd
String在java中的内存模型
1.直接赋值
String s = "abc";
当使用双引号直接赋值时, 系统会检查该字符串在串池(StringTable)中是否存在.
不存在 : 创建新的 存在 : 复用(不创建新的)
这种方式最常用, 代码简单, 节约内存.
2.使用new关键字
char [] chars = {'a','b','c'};
String s1 = new String(chars);
String s2 = new String(chars);
s1和s2不是一个字符串, 因为地址不同.
p99 字符串的比较
String s1 = "abc";//它是在串池中的数据
String s2 = "abc";//变量值一样,s2是复用s1的值
System.out.println(s1 == s2); //true
//-----------------------------
String s3 = new String("abc"); //记录堆里面的地址值
String s4 = "abc"; //记录串池中的地址值
System.out.println(s3 == s4); //false
- "==" 号 比较的原理 :
基本数据类型 : 比较的是具体的数据值
引用数据类型 : 比较的是地址值
- boolean equals 方法(要比较的字符串) 完全一样结果是true, 否则为false
boolean equalsIgnoreCase(要比较的字符串) 忽略大小写的比较
//1.创建两个字符串
String s1 = new String("abc"); //小写
String s2 = "ABC"; //大写
//2.用==号比较
/*基本数据类型 : 比较的是具体的数据值
引用数据类型 : 比较的是地址值 */
//地址值不一样
System.out.println(s1 == s2); //false
//3.比较字符串中的内容是否相等
boolean result1 = s1.equals(s2); //区分大小写,必须完全一样
System.out.println(result1); //true
boolean result2 = s1.equalsIgnoreCase(s2); //不区分大小写
System.out.println(result2); //false
只要是想比较字符串中的内容就必须用String类里的方法
p100 练习 - 用户登录
需求 : 已知正确的用户名和密码, 实现模拟用户登录. 共3次机会, 登录后, 给出相应提示.
public static void logIn() {
String rightUserName = "Qt";
String rightPassword = "123";
Scanner scanner = new Scanner(System.in);
for (int i = 0; i < 3; i++) {
System.out.println("输入用户名:");
String userName = scanner.next();
System.out.println("输入密码:");
String password = scanner.next();
if (userName.equals(rightUserName) && password.equals(rightPassword)) {
System.out.println("用户" + rightUserName + "登录成功.");
return;
} else {
if (i == 2) {
System.out.println("用户" + rightUserName + "的账号被锁定,请与管理员联系.");
} else System.out.println("登录失败,用户名或密码错误.还有" + (2 - i) + "次机会.");
}
}
}
CTRL + Alt + T : 用各种结构包裹所选的代码(比如for,if...).
p101 练习 - 遍历字符串
需求 : 录入一个字符串, 实现在控制台遍历字符串.
- public char charAt(int index) : 根据索引返回字符
- public int length() : 返回此字符串长度
- 数组的长度 : 数组名.length (属性:没有括号)
- 字符串的长度 : 字符串对象.length() (方法:有括号)
- 遍历字符串的for循环 : str.length().fori
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("输入一个字符串:");
String str = s.next();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
System.out.println(c);
}
}
统计字符次数
练习 : 录入一个字符串, 统计当中的大写字母, 小写字母, 数字出现的次数(不考虑其它字符)
//1.需求 : 录入一个字符串, 实现在控制台遍历字符串.
//2.需求 : 录入一个字符串, 统计当中的大写字母, 小写字母, 数字出现的次数(不考虑其它字符)
public class printString_bigSmallNumber {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("输入一个字符串:");
String str = s.next();
countString(str);//调用方法
}
//遍历字符串方法
public static void print_String(String str) {
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
System.out.println(c);
}
}
//统计大小写数字方法
public static void countString(String s){
System.out.println("大写字母有" + big(s) + "个.");
System.out.println("小写字母有" + small(s) + "个.");
System.out.println("数字有" + number(s) + "个.");
}
//大写
public static int big(String s) {
int count = 0;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c >= 'A' && c <= 'Z') {
count++;
}
}
return count;
}
//小写
public static int small(String s) {
int count = 0;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c >= 'a' && c <= 'z') {
count++;
}
}
return count;
}
//数字
public static int number(String s) {
int count = 0;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c >= '0' && c <= '9') {
count++;
}
}
return count;
}
}
p102 练习 : 拼接字符串
需求 : 定义一个方法, 把 int 数组中的数据按照指定的格式拼接成一个字符串返回,调用方法, 并在控制台输出结果. 例如: int[]arr = {1,2,3} --> [1,2,3]
public class arrToString {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5};
String s = arrToStr(arr);
System.out.println(s);
}
//拼接数组成字符串方法
public static String arrToStr(int[] arr) {
if (arr == null) {
return "null";
}
if (arr.length == 0) {
return "[0]";
}
String s = "[";
for (int i = 0; i < arr.length; i++) {
if (i == arr.length - 1) {
s = s + arr[i] + "]";
} else {
s = s + arr[i] + ", ";
}
}
return s;
}
}
字符串反转
练习 : 定义一个方法, 实现字符串反转, 录入一个字符串, 调用方法后, 控制台输出结果.例如, 录入abc, 输出cba
public class reverse {
public static void main(String[] args) {
String s = "123ABC";
System.out.println(reverseString(s));
}
//反转字符串方法
public static String reverseString(String s){
String result = "";
for (int i = s.length()-1; i >= 0; i--) {
char c = s.charAt(i);
result = result + c;
}
return result;
}
}
小问题 :
-
fori是从小到大++循环,forr是从大到小--循环
-
解决Idea中shift+F6快捷键失效问题
在升级到windows11后,idea中的shift+F6不能使用了,感觉是热键冲突了。
右键输入法,->常规 ->兼容性,使用以前版本的微软拼音输入法(开)
练习 - 金额转换
2135 --> 金额(大写) 零 佰 零 拾 零 万 贰 仟 壹 佰 叁 拾 伍 元 (总长度7位)
零0 壹1 贰2 叁3 肆4 伍5 陆6 柒7 捌8 玖9
{'零','壹','贰','叁','肆','伍','陆','柒','捌','玖'}
步骤 :
- 对输入的数据进行校验,(money)大于0, 小于等于9999999.
- 定义方法getCapitalNumber方法, 让数字和大写中文产生一一对应的关系. 定义String数组, 存储0~9的大写, 方法返回形参索引的元素.
- 获得money中的每一位数字, 在获取过程中调用getCapitalNumber方法, 反向拼接成字符串.
- 在获得的字符串中补0, 补到7位(7减去字符串长度).在字符串前面拼接0.
- 定义String数组存储单位, 遍历钱数字符串的同时把单位数组插入进去. 再把大写数字和单位拼接到一个字符串变量(result)中.
package API_String;
import java.util.Scanner;
/*p103 练习 - 金额转换
2135 --> 金额(大写) 零 佰 零 拾 零 万 贰 仟 壹 佰 叁 拾 伍 元 (总长度7位)
零 壹 贰 叁 肆 伍 陆 柒 捌 玖 {'零','壹','贰','叁','肆','伍','陆','柒','捌','玖'}
{'佰','拾','万','仟','佰','拾','元'}
步骤 :
1. 对输入的数据进行校验,(money)大于0, 小于等于9999999.
2. 定义方法getCapitalNumber方法, 让数字和大写中文产生一一对应的关系. 定义String数组, 存储0~9的大写, 方法返回形参索引的元素.
3. 获得money中的每一位数字, 在获取过程中调用getCapitalNumber方法, 反向拼接成字符串.
4. 在获得的字符串中补0, 补到7位(7减去字符串长度).在字符串前面拼接0.
5. 定义String数组存储单位, 遍历钱数字符串的同时把单位数组插入进去. 再把大写数字和单位拼接到一个字符串变量(result)中.*/
public class numberToCapital {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int money = 0;
//对输入的数据进行校验
while (true) {
System.out.println("输入金额:");
money = sc.nextInt();
if (money > 0 && money <= 9999999) {
break;
} else System.out.println("金额无效,重新输入.");
}
//获得money中的每一位数字
String s = "";
while (money != 0) {
int ge = money % 10;
money /= 10;
String capitalNumber = getCapitalNumber(ge);
s = capitalNumber + s;
}
//在获得的字符串中补0
int zero = 7 - s.length();
for (int i = 0; i < zero; i++) {
s = "零" + s;
}
// System.out.println(s);
//插入单位
String[] unit = {"佰", "拾", "万", "仟", "佰", "拾", "元"};
String result = "";
for (int i = 0; i < s.length(); i++) {
result = result + s.charAt(i) + unit[i];
}
System.out.println(result);
}
//数字和大写中文转换方法
public static String getCapitalNumber(int index) {
String[] s = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
return s[index];
}
}
p104 练习 手机号屏蔽(subString方法,截取字符串)
需求 : 录入手机号, 例如13812345678 转换成 138****5678 并输出.
package API_String;
/*手机号屏蔽
需求 : 录入手机号, 例如13812345678 转换成 138****5678 并输出.
*/
public class screenPhoneNumber {
public static void main(String[] args) {
String phoneNumber = "13812345678";
String s = screenNumber(phoneNumber);
System.out.println(s);
}
public static String screenNumber(String phomeNumber){
//subString方法,截取头3位,和后4位
String start = phomeNumber.substring(0, 3);
String end = phomeNumber.substring(7);//从7到最后
//拼接
return start + "****" + end;
}
}
身份证号码信息查看
需求 : 录入身份证号码, 例如1122198603191121 打印 此人信息为:出生日期: XXXX年X月X日 性别为: 男/女
/*身份证信息 1,2位:省份. 3,4位:城市. 5,6位:区县. 7-14位:出生年月日. 15,16位:所在地派出所. 17位性别(奇数男性,偶数女性). 18位:个人信息码(随机生成)*/
package API_String;
/*身份证号码信息查看
需求 : 录入身份证号码, 例如210106198603191121 打印 此人信息为:出生日期: XXXX年X月X日 性别为: 男/女*/
public class IDMassage {
public static void main(String[] args) {
String IDNumber = "111111199006291220";
getMassage(IDNumber);
}
public static void getMassage(String IDNumber) {
//截取有用的部分
String year = IDNumber.substring(6, 10);
String month = IDNumber.substring(10, 12);
String day = IDNumber.substring(12, 14);
char gender = IDNumber.charAt(16);
//输出信息
System.out.println("此人信息位" + "出生日期: " + year + "年" + month + "月" + day + "日");
//判断性别 '字符' - 48 把字符所对应的数字和48('0')相减(差值)
if ((gender - 48) % 2 == 0) {
System.out.println("性别:女");
} else System.out.println("性别:男");
}
}
游戏骂人敏感词替换
需求 : 把字符串中的特定词替换成(replace方法)$, 例如"你tmd是sb啊." -> "你$$$是$$$啊."
public class replaceWords {
public static void main(String[] args) {
String dialog = "你tmd是sb啊.";
String s = replaceW(dialog);
System.out.println(s);
}
//敏感词替换方法 , replace
public static String replaceW(String s) {
//定义词库
String [] words = {"sb","tmd","nmb","cnm"};
//循环词库数组,把s(形参字符串)中如果有词库中的词,都替换成***
for (int i = 0; i < words.length; i++) {
s = s.replace(words[i],"$$$");
}
return s;
}
}
p105 StringBuilder的基本操作
构造方法 :
- 空参构造 创建一个空白的可变字符串对象
- String 类型参数 根据字符串的内容, 创建可变字符串对象
成员方法 :
- append(任意类型) 添加数据, 返回对象本身
- reverse() 反转容器中的内容
- length() 返回长度
- toString() StringBuilder转换位String
打印StringBuilder时是属性值而不是地址值
p105 练习 - 对称字符串
需求 : 录入一个字符串, 程序判断是否是对称字符串.例如:对称字符串: 12321 , 111; 非对称字符串: 123
public class StringBuilderExercise_1 {
public static void main(String[] args) {
System.out.println(isReturnString());
}
public static boolean isReturnString(){
Scanner sc = new Scanner(System.in);
System.out.println("输入一个字符串:");
String s = sc.next();
String sb = new StringBuilder(s).reverse().toString();
return s.equals(sb);
}
}
练习 - 数组转字符串
需求: 定义一个方法, 把int 数组中的数据按照指定格式拼接成一个字符串返回.
例如: 数组位int[] arr = {1,2,3} 输出结果 : [1, 2, 3]
public class StringBuilderExercise_2 {
public static void main(String[] args) {
int[] arr = {1, 2, 3};
System.out.println(arrayToString(arr));
}
public static String arrayToString(int[] arr) {
StringBuilder sb = new StringBuilder();
sb.append("[");
for (int i = 0; i < arr.length; i++) {
if (i == arr.length - 1) {
sb.append(arr[i]).append("]");
} else
sb.append(arr[i]).append(", ");
}
return sb.toString();
}
}
使用StringBuilder的场景 : 1. 字符串的拼接. 2. 字符串的反转.
p106 StringJoiner
概述
- 跟StringBuilder一样, 也是一个容器, 创建后里面的内容是可变的.
- 作用: 提高字符串的操作效率, 编码简洁.
- JDK8出现的
构造方法
StringJoiner(间隔符号) 如("--") 1--2--3
StringJoiner(间隔符号, 开始符号, 结束符号) (", "[","]") [1, 2, 3]
成员方法
- add(添加的内容) 添加数据, 返回对象本身
- length() 返回长度
- toString() 返回一个字符串(拼接的结果)
public class StringJoinerDemo {
public static void main(String[] args) {//
StringJoiner sj = new StringJoiner(", ","[","]");
String s = sj.add("a").add("b").add("c").add("d").toString();
System.out.println(s);
}
} // [a, b, c, d]
字符串-总结
- String - 字符串类, 定义了很多操作字符串的方法
- StringBuilder - 可变容器, 可以高效的拼接/反转字符串
- StringJoiner - JDK8出现, 可以高效,方便的拼接字符串.
p107 字符串相关的底层原理
CTRL+F12 在类中查找方法
字符串拼接时有变量参与: 在内存中创建了很多对象, 浪费空间, 时间也非常慢.
所以如果很多字符串变量拼接, 不要直接 "+" . 在底层会创建多个对象, 浪费时间,浪费性能.
问题: 下列代码的运行结果是?
public class StringsCompare {
public static void main(String[] args) {
String s1 = "abc";//记录串池中的地址值
String s2 = "ab";
String s3 = s2 + "c";//底层在堆中new StringBuilder对象来拼接
System.out.println(s1 == s3);
}
} //false
问题: 下列代码的运行结果是?
String s1 = "abc";//记录串池中的地址值
String s2 = "a"+"b"+"c";//没有变量参与,复用串池中的字符串
System.out.println(s1 == s2);
//true
字符串原理小结
扩展底层原理1: 字符串存储的内存原理
- 直接赋值会复用字符串常置池中的
- new出来不会复用,而是开辟一个新的空间
扩展底层原理2: ==号比较的到底是什么?
- 基本数据类型比较数据值
- 引用数据类型比较地址值
扩展底层原理3: 字符串拼接的底层原理
- 如果没有变量参与,都是字符串直接相加,编译之后就是拼接之后的结果,会复用串池中的字符串。
- 如果有变量参与,会创建新的字符串,浪费内存。
扩展底层原理4: StringBuilder提高效率原理
- 所有要拼接的内容都会往StringBuelder中放, 不会创建很多无用的空间, 节约内存
扩展底层原理5: StringBuilder原码分析
- 默认创建一个长度为16的字节数组
- 添加的内容长度小于16,直接存
- 添加的内容大于16会扩容(原来的容量*2+2)
- 如果扩容之后还不够,以实际长度为准
p108 练习 - 罗马数字
需求: 录入一个字符串. 要求1:长度小于等于9. 要求2:只能有数字. 将内容变成罗马数字
阿拉伯数字和罗马数字对比关系
I - 1, II - 2, III - 3, IV - 4, V - 5, VI - 6, VII - 7, 8 - VIII ,9 - IX - 9
注意点: 罗马数字里面没有0, 如果键盘录入数字包含0, 可以变成 "",(长度为0的字符串)
p109 练习 - 字符串旋转
需求: 给定两个字符串, A 和 B. A的旋转操作就是将A最左边的字符移动到最右边. 例如,A = "abcde", 在移动一次之后结果就是"bcdea". 如果在若干次调整操作之后, A 能变成 B, 那么返回True.如果不能匹配成功, 则返回false
标签:07,System,println,API,字符串,JavaSE,out,public,String
From: https://www.cnblogs.com/lg369/p/17742841.html