Java学习笔记8.——字符串
Java学习笔记8.——字符串
前言
这节讲了字符串的比较,拼接,创建的底层原理,以及常用的几种String方法和对象。
比如STringBuilder对象,StringJoiner对象,这个对象是jdk8以后出现的。
replace方法,charAt方法,subString方法。
一、API
api(Application Programming Interface):应用程序编程接口。
官方写好封装好的东西,我们可以直接使用不需要自己编写。
官方也提供了jdk_api帮助文档,可以在网上下载使用。
二、String
字符串和任何东西拼接都是字符串。
“123”+“456” = “123456”
“321”+true = “321true”
“技术”+200 = “技术200”
1.字符串被创建后其值就不能被改变,看着赋的值也是新的字符串。
- 这就和引用型的原理是一样的。赋的新值字符串想到于在堆区创建了新的空间,原来的对象指向了新的空间地址。
2.字符串是java定义好的类,在java.lang中,使用时不需要再导包
3.所有字符串文字都是此包的对象
String name = "专注技术200年";
name = "厚德载物";
这上面就是创建了两个字符串,只是name指向了新的字符串地址。
1.String两种赋值方式
String字符串有两种方式,第二种方式在api帮助文档里也能找到。
public static void main(String[] args) {
//1.直接赋值
String s1 = "abc";
System.out.println(s1);
//2.使用new方式创建
//1.空参构造方法,这种没啥必要,输出什么也没有
String s2 = new String();
System.out.println(s2);
//2.使用有参构造方法,也没必要,类似于创建数组一样
String s3 = new String("abc");
System.out.println(s3);
//3.使用字符数组为参数构造,这种用于改变某一个单词的时候
char[] c = {'a','b','c','d'};
String s4 = new String(c);
System.out.println(s4);
//4.使用字节数组为参数构造,//用于网络传数据的时候
byte[] b = {97,98,99,100};
String s5 = new String(b);
System.out.println(s5);
}
2.String内存
在之前学过了栈,方法运行时进栈,运行完就出栈。
堆区,使用new关键字时就会在堆区创建新的空间
方法区,字节码文件(.class)进入方法区临时存储
现在学串池,以前在方法区中,现在在堆区中
- 直接赋值的可以在串池中寻找。
- 若是没有该值则在串池中新建一个,把地址值传过去。
- 如果有该值则可以直接复用。
- 使用new创建的则是在堆区中创建。
- 比如上面的char数组,在堆区中创建了一个数组,把地址值赋给c,然后s4使用new关键字创建了一个字符串,这个字符串的地址是新开辟的空间地址。如果再创建一个字符串s6,使用同样的方式创建,那么这个s6的地址值也是一个新的空间开辟的地址值。
可以对比看出不会复用,只会创建新的空间
到现在算是有了些大概的了解了。
- 比如上面的char数组,在堆区中创建了一个数组,把地址值赋给c,然后s4使用new关键字创建了一个字符串,这个字符串的地址是新开辟的空间地址。如果再创建一个字符串s6,使用同样的方式创建,那么这个s6的地址值也是一个新的空间开辟的地址值。
3.String字符串的比较
比较实用等于符号来比较的。
- 基本数据类型 == 比较的是具体的值
- 引用型数据类型 == 比较的是具体的地址值,而不是里面的值
String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2);
//案例2
String s3 = new String("abc");
System.out.println(s1 == s3);//false
刚刚说过,引用型数据类型比较值是比较地址值,s1与s2都是直接赋值使用的是串池中的,s2是复用s1开辟的地址值,所以s1和s2的地址值一样,结果是true;
s3的创建类型是new方式,所以其地址值在堆区中而不在串池区,所以和s1的地址值不一样,结果为false
难道想比较字符串的具体值内容(不是地址值)就不可以了吗?
所以java官方提供了两种方法。
equls() 比较内容
equlsIgnoreCase()比较内容,忽略大小写
String s1 = "abc";
String s12 = "ABc";
System.out.println(s1==s12);
System.out.println(s12);
String s3 = new String("abc");
System.out.println(s3);
boolean result = s3.equals(s1);
boolean result2 = s3.equalsIgnoreCase(s12);
System.out.println(result);
System.out.println(result2);
所以键盘输入的字符串也可以用equals方法进行比较内容,那地址值的话根据底层逻辑发现也是new出来的一个空间,所以与直接赋值或者new的字符串用==符号不相等,结果为false。
三、案例
1.用户登录
用户登录
需求:已知正确的用户名和密码,请用程序实现模拟用户登录。
总共给三次机会,登录之后,给出相应的提示
package String;
import java.util.Scanner;
public class Test2 {
public static void main(String[] args) {
// 用户登录
//需求:已知正确的用户名和密码,请用程序实现模拟用户登录。
//总共给三次机会,登录之后,给出相应的提示
//1.先确定正确的用户名和密码,自己设置。
String name = "user";
String passwd = "987654321";
//2.用户键盘录入用户名和密码
Scanner sc = new Scanner(System.in);
boolean flag = true;
//3.录入之后比较用户名和密码的值,用equals
// 4.可以有三次密码输错的机会,只要有1次就可以登录成功就可以。
for (int i = 0; i < 3; i++) {
System.out.println("请输入用户名");
String sname = sc.next();
System.out.println("请输入密码");
String spwd = sc.next();
boolean nresult = name.equals(sname);
boolean presult = passwd.equals(spwd);
if (nresult && presult){
System.out.println("登录成功!!!");
flag = false;
break;
}else {
System.out.println("用户名或者密码错误,请重新登录");
}
}
if (flag){
System.out.println("今日三次机会已用完,请明日再试");
}
}
}
2.遍历字符串
charAt(int index)这个方法根据索引值位置返回字符串的内容
如果s1.charAt(0)则是从首位开始返回字符串内容,这里索引为0也是字符串也有索引,每一个字符都有一个索引位置.
length()因为数组中长度是属性,但是这里是方法所以有括号
public static void main(String[] args) {
//1.从键盘录入一个字符串
Scanner sc = new Scanner(System.in);
System.out.println("请输入任意个字符");
String s1 = sc.next();
//2.遍历字符串使用charat
// s1.charAt(0);
for (int i = 0; i < s1.length(); i++) {
System.out.print(s1.charAt(i)+" ");
}
//3.length()长度,数组中长度是属性没有括号,这里长度是方法所以有括号
}
3.统计字符
录入一个字符串,分别统计大小写字母和数字的出现次数,其他字符也统计。
这个点我忘了ASCII码值,可以直接使用’a’这样也代表是正确的,不用专门去把字符改成数字,知道具体的值就可以了。
或许可以把之强制转成int整型判断然后再转成字符型
package String;
import java.util.Scanner;
public class StringTest4 {
public static void main(String[] args) {
//1.键盘录入一个字符
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串,只能包含英文字母和数字");
String s1 = sc.next();
//2.比较字符产中的大小写字母,和数字出现的次数
//遍历出字符串中的字符放进数组里面。
char[] c = new char[s1.length()];
for (int i = 0; i < c.length; i++) {
c[i] = s1.charAt(i);
}
//使用count三个变量统计次数
int charcount1 = 0;
int charcount2 = 0;
int numcount = 0;
int count= 0;
// 使用字符判断大小写和数字
for (int i = 0; i < c.length; i++) {
if (c[i] >= 'a' && c[i] <= 'z'){
charcount1++;
}else if (c[i] >= 'A' && c[i] <= 'Z'){
charcount2++;
}else if (c[i] >= '0' && c[i] <= '9'){
numcount++;
}else {
count++;
}
}
System.out.println(charcount1+" "+charcount2+" "+numcount);
System.out.println("其他字符:"+count);
}
}
4.拼接字符串
拼接字符串
定义一个方法,把 int数组中的数据按照指定的格式拼接成一个字符串返回,调用该方法,并在控制台输出结果。
例如:
数组为int[]arr = {1,2,3};
执行方法后的输出结果为:[1,2,3]
package String;
public class StringTest5 {
public static void main(String[] args) {
// 拼接字符串
//定义一个方法,把 int数组中的数据按照指定的格式拼接成一个字符串返回,调用该方法,并在控制台输出结果。
//例如:
//数组为int[]arr = {1,2,3};
//执行方法后的输出结果为:[1,2,3]
//1.定义1个方法
int[] arr = null;
if (arr!=null){//需要考虑到数组的多种情况
System.out.println(motage(arr));
}
//2.需要数组,然后拼接
}
public static String motage(int[] arr){
String s = "[";
for (int i = 0; i < arr.length; i++) {
s = s + arr[i];
if (i<= arr.length -2){
s = s + ",";
}
}
s = s + "]";
return s;
}
}
5.反转字符串
定义一个方法,实现字符串反转。
键盘录入一个字符串,调用该方法后,在控制台输出结果例如,键盘录入abc,输出结果cba
package String;
import java.util.Scanner;
public class StringTest6 {
public static void main(String[] args) {
// 字符串反转
//定义一个方法,实现字符串反转。
//键盘录入一个字符串,调用该方法后,在控制台输出结果例如,键盘录入abc,输出结果cba
toArr();
}
public static char[] toArr(){
//1.录入一个字符串
Scanner sc = new Scanner(System.in);
String s = sc.next();
//2.把字符串放进数组,用charAt,因为字符串是由一个个字符串起来的,所以这里使用字符数组
char[] arr = new char[s.length()];
for (int i = 0; i < arr.length; i++) {
arr[i] = s.charAt(i);
}
// arr[0] = s.charAt(0);
//3.把数组反转,然后输出来
char temp ;
for (int i = 0,j= arr.length-1; i<j; i++,j--) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]);
}
return arr;
}
}
6.数字转换
把2135元变成这种 零佰零拾零万贰仟壹佰叁拾伍元
这个考到了charAt()方法以及字符拼接
package String;
public class StringTest7 {
public static void main(String[] args) {
String s1 = "2135";
//如果数字长度小于等于7就可以依次填上去
//1.取出字符,比较对应的数字对应中文
char c ;
String s2 = "";
//少几个长度就在前面加几个零
int length = 7-s1.length();
for (int i = 0; i < length; i++) {
s2 = s2 +"零";
}
System.out.println(s2);
for (int i = 0; i <= s1.length()-1; i++) {
c = s1.charAt(i);
switch (c){
case '0':
s2 = s2 + "零";
break;
case '1':
s2 = s2 + "壹";
break;
case '2':
s2 = s2 + "贰";
break;
case '3':
s2 = s2 + "叁";
break;
case '4':
s2 = s2 + "肆";
break;
case '5':
s2 = s2 + "伍";
break;
case '6':
s2 = s2 + "陆";
break;
case '7':
s2 = s2 + "柒";
break;
case '8':
s2 = s2 + "捌";
break;
case '9':
s2 = s2 + "玖";
break;
}
}
System.out.println(s2);
String[] s3 = {"佰","拾","万","仟","佰","拾","元"};
String s4 = "";
for (int i = 0; i < s2.length(); i++) {
s4 = s4 + s2.charAt(i)+s3[i];
}
System.out.println(s4);
}
}
因为金额是数字不是字符串,所以可以使用数字取个位数的方法放进数组或者字符串里,后续步骤都是一样的。
7.手机号屏蔽subString()
使用索引和拼接,数组
String subString(int beginIndex,int endIndex),左闭右开区间
String subString(int beginindex),从这个位置截取到末尾
package String;
public class StringTest8 {
public static void main(String[] args) {
//手机号屏蔽
//1.手机号长度11位,前面三位,后面四位显示,中间四位用*显示,用字符串装
String s1 = "12345678901";
String s2 = "";
char integer[] = new char[s1.length()];
//2.使用charAt,并且判断在哪一位这里可以用数组索引
for (int i = 0; i < s1.length(); i++) {
integer[i] = s1.charAt(i);
}
for (int i = 0; i < integer.length; i++) {
if ((i<=2&&i>=0)||(i<=10&&i>=7)){
s2 = s2+integer[i];
}else{
s2 = s2+"*";
}
}
System.out.println(s2);
}
}
输出结果:123****8901
8.根据身份证输出年月日,性别
//1、2位:省份
//3、4位:城市
//5、6位:区县
//7-14位:出生年、月、日
//15、16位:所在地派出所
//17位:性别(奇数男性,偶数女性)
//18位:个人信息码(随机产生)
package String;
public class StringTest9 {
public static void main(String[] args) {
// 1、2位:省份
//3、4位:城市
//5、6位:区县
//7-14位:出生年、月、日
//15、16位:所在地派出所
//17位:性别(奇数男性,偶数女性)
//18位:个人信息码(随机产生)
String s = "500229200103270213";
String s1 = s.substring(6,10);
s1 = s1 + "年"+ s.substring(10,12);
s1 = s1 + "月" + s.substring(12,14) +"日";
System.out.println("人物信息为:");
System.out.println("出生年月日:"+s1);
char s2 = s.charAt(17);
if (s2%2==0){
System.out.println("性别为:女");
}else {
System.out.println("性别为:男");
}
}
}
9.关键词屏蔽,replace()
replace(旧值,新值) 替换
public class StringTest10 {
public static void main(String[] args) {
//替换敏感词
String s = "12jo,fojwei,jfSBe,jfoweTMDjfoawej";
String[] arr = {"TMD","TNND","SB","CNMD"};
for (int i = 0; i < arr.length; i++) {
s = s.replace(arr[i], "***");
}
System.out.println(s);
}
}
四、综合知识
1.StringBuilder
StringBuilder可以看成一个容器,创建之后里面的内容是可变的
- 作用是提高字符串的操作效率
适用于拼接和反转的时候
前面我们知道字符串的内容创建之后是不可以修改的,赋值一个新的字符串也是创建了一个新的空间赋值的地址值。
所以上面案例中很多拼接都是创建的新的字符串,并不是真的拼接成一个了。如果要拼接多个字符串,从1拼接到1000000那就需要拼接即创建这么多字符串,效率低下,所以可以使用StringBuilder这个,因为他创建之后里面的内容可变,没有新增空间创建新的字符串,是在原来空间里操作的。
StringBuilder有两种方法构造方法,有参和无参
方法名 | 说明 |
---|---|
public StringBuilder() | 创建一个空白可变字符对象,不含有任何内容 |
public StringBuilder(String str) | 根据字符串的内容,创建一个可变字符串的对象 |
StringBuilder的常见4种方法
方法名 | 说明 |
---|---|
public StringBuilder append(任意类型) | 添加数据,并返回对象本身 |
public StringBuilder reverse() | 反转容器中的内容 |
public int length() | 返回长度(字符出现的个数) |
public String toString() | 通过toString()就可以实现把StringBuilder对象转换为String字符串 |
(有)public StringBuilder delete(int start,int end) | 删除数据,左闭右开区间,但是0-大于sb数据长度也能删除成功不报错(我使用的IDEA) |
StringBuilder stringBuilder = new StringBuilder("123456789");
System.out.println(stringBuilder);
这里以为输出来的会是StringBuilder 对象地址,但是结果是具体值。
打印对象不是地址值,是属性值。
百度了一下不是很懂,打印的是StringBuilder 对象的内存地址,而不是变量本身的地址。且System.out.println()方法内部会调用toString()方法将对象转换为字符串。这个先暂时保留。
1.对称字符串
public static void main(String[] args) {
//对称字符串
// String s = "123321";
// StringBuilder sb = new StringBuilder(s);
// sb.reverse();
// boolean equals = sb.toString().equals(s);
// System.out.println(equals);
StringBuilder sb1 = new StringBuilder("12");
StringBuilder sb2 = new StringBuilder("12");
boolean equals = sb1.equals(sb2);
System.out.println(equals);
注释部分没有问题,就是下面我发现使用equals不能使他们两个的内容相同…我去看了下api开发文档,没有StringBuilder比较相同内容的方法,我猜可能是我这个落后了,也有可能是没有必要,因为他只是字符串的使用工具,最后都是为字符串服务所以没必要。
2.拼接字符串
package String;
public class StringTest12 {
public static void main(String[] args) {
// 拼接字符串
//需求:定义一个方法,把 int数组中的数据按照指定的格式拼接成一个字符串返回。
//调用该方法,并在控制台输出结果。
//例如:数组为int[]arr = {1,2,3};执行方法后的输出结果为:[1,2,3]
int[] arr = {1,2,3};
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]);
}
}
sb.append("]");
System.out.println(sb.toString());
}
}
2.StringJoiner
也可以看出一个容器,里面的内容也是可变的。
- 作用:提高字符串的操作效率,而且代码简洁
- 出现于jdk8
构造方法
方法名 | 说明 |
---|---|
public StringJoiner(间隔符号) | 创建一个StringJoiner对象,指定拼接时的间隔符号 |
public StringJoiner(间隔符号,开始符号,结束符号) | 指定拼接时的间隔符号,开始符号,结束符号 |
感觉就是比StringBuilder多了个间隔符号的作用,然后没有空参构造
方法名 | 说明 |
---|---|
public StringJoiner add(添加内容) | 添加数据(只能添加字符序列),返回对象本身 |
public int length() | 返回长度(字符出现的个数) |
public String toString() | 返回一个字符串,(该字符串就是拼接之后的结果) |
五、字符串底层原理
1.字符串拼接
刚刚了解了那么多字符串拼接,也使用了字符串拼接的方法和对象,最终到底都躲不过那个提高字符串操作效率。
1.没有变量拼接
String s = "abc";
String s1 = "a"+"b"+"c";
System.out.println(s==s1);
拼接的时候没有变量,都是字符串会触发字符串的优化机制(常量池里面创建),在编译的时候就已经是最终结果了。
假如常量池里有abc,则直接复用这个字符串。所以结果为true。
2.有变量拼接
String s1 = "a";
String s2 = s1 + "b";
String s3 = s2 + "c";
1.mian方法进栈,s1时在串池中创建“a”
2.s2时串池中创建“b”,此时堆区中创建了new StringBuilder()对象,里面放了“ab”,然后使用toString变成字符串,再把值返回给s2.
3.s3时,串池中创建“c”,并且堆区中会再次创建一个new StringBuilder()对象,里面放了“abc”,然后使用toString变成字符串,再把值返回给s3.
最后发现一个加号两个对象,多占空间啊。
3.jdk8字符串拼接的底层原理
String s1 = "a";
String s2 = "b";
String s3 = "c";
String s4 = s1 + s2 + s3 + s4;
它会先预估字符串的长度有多长,创建一个数组然后再把数填进去再变成字符串。
如果也有变量参与,也会在内存中创建很多对象浪费空间,时间也非常慢,所以以后还是尽量不要有变量参与,尽量不要用+的方式。
jdk8以前:系统底层自动创建一个StringBuilder对象,然后再调用append方法完成拼接。拼接之后调用toString方法转换为String类型,而toString方法的底层源码是直接new了一个字符串对象。
jdk8以后:系统会预估要字符串拼接之后的大小,把拼的内容放进数组中此时也产生了一个新的字符串…
2.StringBuilder提高效率
所有拼接的内容都会放在StringBuilder中,是可变内容,所以不会创建很多无用的空间,节约内存。
容量,长度区别(银行卡中长度为9,但是能放的金额很多几千上百亿都能装下),StringBuilder的长度就是int的范围那么大
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
System.out.println(sb.capacity());
System.out.println(sb.length());
sb.append("abcdefghijklmnopqrstuvwxyz");
System.out.println(sb.capacity());
System.out.println(sb.length());
sb.append("abcdefghijklmnopqrstuvwxyz1234567890");
System.out.println(sb.capacity());
System.out.println(sb.length());
}
扩容1:每次扩容的时候都是老容量*2 + 2 = 34
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
System.out.println(sb.capacity());
System.out.println(sb.length());
sb.append("abcdefghijklmnopqrstuvwxyz1234567890");
System.out.println(sb.capacity());
System.out.println(sb.length());
}
扩容2:如果超出*2+2的容量则以实际容量为准 = 36,长度也36,16+20(20是超出的部分。)
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
System.out.println(sb.capacity());
System.out.println(sb.length());
sb.append("abcdefghijklmnopqrstuvwxyz1234567890");
System.out.println(sb.capacity());
System.out.println(sb.length());
sb.append("abcdefghijklmnopqrstuvwxyz1234567890111");
System.out.println(sb.capacity());
System.out.println(sb.length());
}
可以连续扩容
1.转换罗马数字
转换罗马数字
键盘录入一个字符串,要求1∶长度为小于等于9要求2:只能是数字将内容变成罗马数字
下面是阿拉伯数字跟罗马数字的对比关系:
l - 1、ll - 2、II - 3、IV - 4、V - 5、VlI-6、VII - 7、VI -8、IX - 9注意点:
罗马数字里面是没有0的 如果键盘录入的数字包含0,可以变成””(长度为0的字符串)
public static void main(String[] args) {
//转换罗马数字
//键盘录入一个字符串,要求1∶长度为小于等于9要求2:只能是数字将内容变成罗马数字
//下面是阿拉伯数字跟罗马数字的对比关系:
//l - 1、ll - 2、II - 3、IV - 4、V - 5、VlI-6、VII - 7、VI -8、IX - 9注意点:
//罗马数字里面是没有0的 如果键盘录入的数字包含0,可以变成””(长度为0的字符串)
//1.录入字符串
Scanner sc = new Scanner(System.in);
System.out.println("请输入长度小于9的数字");
String s1 = sc.next();
//2.判断长度小于等于9
convert(s1);
//3.将数字变成罗马数字,replace(旧值,新值)替换
}
//3.将数字变成罗马数字,replace(旧值,新值)替换
public static void convert(String s1){
String[] number = {"0","1","2","3","4","5","6","7","8","9"};
String[] luoma = {"","I","II","III","IV","V","VI","VII","VIII","IX"};
for (int i = 0; i < number.length; i++) {
s1 = s1.replace(number[i], luoma[i]);
}
System.out.println(s1);
}
这个没写完,后面重新写了个其他的方法,这里没有判断数字和长度。(其实我总以为自己判断了,,还是读题有点不严谨)
2.旋转字符
调整字符串
给定两个字符串,A和B。
A的旋转操作就是将A最左边的字符移动到最右边。
例如,若A= ‘abcde’,在移动一次之后结果就是’bcdea’如果在若干次调整操作之后,A能变成B,那么返回True。如果不能匹配成功,则返回false
public static void main(String[] args) {
//调整字符串
//给定两个字符串,A和B。
//A的旋转操作就是将A最左边的字符移动到最右边。
//例如,若A= 'abcde',在移动一次之后结果就是'bcdea'如果在若干次调整操作之后,A能变成B,那么返回True。如果不能匹配成功,则返回false
String s1 = "abcde";
String s2 = "deabc";
boolean flag = chekStr(s1,s2);
if (flag){
System.out.println("匹配成功");
}else {
System.out.println("匹配不成功");
}
}
public static boolean chekStr(String s1,String s2){
String stemp = s1;
//假如匹配不成功
boolean flag = false;
for (int i = 0;i < s2.length();i++) {
//截取第1位
String temp1 = stemp.substring(0,1);
//截取第2位到末尾
String temp2 = stemp.substring(1);
//把后面的先添加再添加第1位,这样看起来就像旋转的了,然后转成字符串
StringBuilder sb = new StringBuilder();
stemp = sb.append(temp2).append(temp1).toString();
if (stemp.equals(s2)){
System.out.println(stemp);
flag = true;
break;
}
}
return flag;
}
还可以用字符数组,调整数据的位置就可以了。
package String;
public class StringTest14Case2 {
public static void main(String[] args) {
//调整字符串
//给定两个字符串,A和B。
//A的旋转操作就是将A最左边的字符移动到最右边。
//例如,若A= 'abcde',在移动一次之后结果就是'bcdea'如果在若干次调整操作之后,A能变成B,那么返回True。如果不能匹配成功,则返回false
String s1 = "abcde";
String s2 = "deabc";
boolean flag = false;
for (int i = 0; i < s2.length(); i++) {
s1 = chekStr(s1);
if (s1.equals(s2)){
System.out.println(s1);
flag=true;
break;
}
}
if (flag){
System.out.println("匹配成功");
}else {
System.out.println("匹配失败");
}
}
public static String chekStr(String s1){
char[] c = s1.toCharArray();
char first = c[0];
for (int i = 1; i < c.length; i++) {
c[i-1] = c[i];
}
c[c.length-1]=first;
String s = new String(c);
return s;
}
}
3.把字符串转成数字转成字符串
给定两个以字符串形式表示的非负整数num1和num2,返回num1和num2的乘积,它们的乘积也表示为字符串形式。注意:需要用已有的知识完成。
ASCII码值,字符串转变成字符数组,字符数组转换成整型数字
package String;
public class StringTest17 {
public static void main(String[] args) {
///*给定两个以字符串形式表示的非负整数num1和num2,返回num1和num2的乘积,它们的乘积也表示为字符串形式。注意:需要用已有的知识完成。*/
String s1 = "256";
String s2 = "2";
boolean b = chek(s1);
boolean b2 = chek(s2);
if (b && b2){
int num1 = toInt(s1);
int num2 = toInt(s2);
StringBuilder sb = new StringBuilder(num1*num2);
System.out.println(sb);
}else {
System.out.println("不是非负整数,字符串不合规则");
}
}
public static boolean chek(String s){
char[] c1 = s.toCharArray();
for (int i = 0; i < c1.length; i++) {
if (c1[i]>'9'||c1[i]<'0'){
return false;
}
}
return true;
}
public static int toInt(String s){
char[] c1 = s.toCharArray();//[1,2,3,4,5,6]
int num1 = 0 ;
//把其转为整型,且-48
for (int i = 0; i < c1.length; i++) {
num1 = num1*10 + c1[i]-48;
}
return num1;
}
}
4.返回单词
给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。
返回字符串中最后一个单词的长度。
单词是指仅由字母组成、不包含任何空格字符的最大子字符串。
示例1:输入:s = "Hello wor1d“ 输出:5
解释:最后一个单词是"wor1d”,长度为5。
示例2:输入:s = “fly me tothe moon” 输出:4
解释:最后一个单词是"moon”,长度为4。
示例3:输入:s = “luffy is still joyboy” 输出:6
解释:最后一个单词是长度为6的“joyboy”。
public static void main(String[] args) {
///*给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。
//返回字符串中最后一个单词的长度。
//单词是指仅由字母组成、不包含任何空格字符的最大子字符串。
//示例1:输入:s = "Hello wor1d“ 输出:5
//解释:最后一个单词是"wor1d”,长度为5。
//示例2:输入:s = "fly me tothe moon" 输出:4
// 解释:最后一个单词是"moon”,长度为4。
//示例3:输入:s = "luffy is still joyboy" 输出:6
//解释:最后一个单词是长度为6的“joyboy”。*/
StringBuilder sb = new StringBuilder("luffy is still joyboy");
String s = sb.reverse().toString();
char[] c = s.toCharArray();
int count = 0;
for (int i = 0; i < c.length; i++) {
if (c[i] == ' '){
count = i;
break;
}
}
// String s2 = s.substring(0, count);
// StringBuilder sb2 = new StringBuilder(s2).reverse();
System.out.println(count);
}
总结
- 1.api开发文档等于java字典
- 2.String 的两种赋值方式,一个在串池,一个在堆区
- 3.==比较的内容
- 基本数据类型比较的具体的值
- 引用数据类型比较的是地址值
- 4.String拼接的原理
- 没有变量参与时,在编译时就完成拼接,(如果串池有拼接好的就是复用串池中的)
- 有参数时就会在堆区创建StringBuilder对象拼接,然后使用toString变成字符串返回
- 5.StringBuilder提高字符串操作效率,因为空间内内容可变,不会无故增加新的空间,节约空间
- 6.STringBuilder的范围与int一样
- 扩容:老容量*2+2
- 扩容:如果超过上面,那就是老容量+超出部分的长度,实际容量为准
只有返回值才是使用后的结果
1.char charAt(int index)
2.String subString(int beginIndex,intendIndex),左闭右开区间
3.String subString(int beginindex),从这个位置截取到末尾
4.replace(旧值,新值) 替换
5.StringBuilder容器,里面的内容可变,提升字符串操作效率
6.StringJoiner(间隔符号),与STringBuilder有些类似,这个在添加时有间隔符号