于是,虚度的光阴换来了模糊
—— 24.5.8
一、String基础知识以及创建
1.String介绍
1.概述
String类代表字符串
2.特点
a.Java程序中的所有字符串字面值(如“abc”)都作为此类的实例(对象)实现
凡是带双引号的,都是String的对象
String s = "abc"
"abc"就是对象,String就是对象的数据类型,s就是对象名
b.字符串是常量,它们的值在创建之后不能更改
String s ="he11o"
S += "world" —> 会产生新对象
c.String 对象是不可变的,所以可以共享
String s1 = "abc"
String s2 = "abc"
package S57String; public class Demo161String1 { public static void main(String[] args) { String s1 = "abc"; String s2 = "abc"; System.out.println(s1==s2); // 比较地址值 true } }
2.String的实现原理
1.jdk8的时候:String底层是一个被final修饰的char数组-> private final char[] value;
2.jdk9开始到之后:底层是一个被final修饰的byte数组-> private final byte[] value;
一个char类型占2个字节
一个byte类型占1个字节 —> 省内存空间
字将串定义完之后,数组就创建好了,被final一修饰,数组的地址值直接定死
3.String的创建
1.String() —> 利用string的无参构造创建string对象
2.String(string original) —> 根据字符串创建string对象3.String(char[] value) —> 根据char数组创建string对象
4.String(byte[] bytes) —> 通过使用平台的默认字符解码指定的 byte 数组,构造一个新的 string对象
a、平台:操作系统
b、操作系统默认字符集:GBK
GBK:一个中文占2个字节
UTF-8:一个中文占3个字节
而且,中文对应的字节一般都是负数
代码在idea中写的,idea启动的时候,会自动加一个启动参数,此启动参数为UTF-8
-Dfile.encoding5.简化形式:String 变量名 =" ”
package S57String; public class Demo162String2Create { public static void main(String[] args) { // 1.String() —> 利用string的无参构造创建string对象 String s1 = new String(); System.out.println("s1="+s1); // 2.String(string original) —> 根据字符串创建string对象 String s2 = new String("abc"); System.out.println("s2="+s2); // 3.String(char[] value) —> 根据char数组创建string对象 char[] chars = {'a','b','c'}; String s3 = new String(chars); System.out.println("s3="+s3); // 4.String(byte[] bytes) —> 通过使用平台的默认字符解码指定的 byte 数组,构造一个新的 string对象 byte[] bytes1 = {97,98,99}; String s4 = new String(bytes1); System.out.println("s4="+s4); // 三个负数代表中文,在ASCII表中找不到,所以无法正常显示 byte[] bytes2 = {-97,-98,-99}; String s5 = new String(bytes2); System.out.println("s5="+s5); byte[] bytes3 = {-28,-67,-96}; String s6 = new String(bytes3); System.out.println("s6="+s6); // 5.简化形式:String 变量名 =" ” String s7 = "abc"; System.out.println("s7="+s7); } }
1.string(char[] value,int offset,int count) —> 将char数组的一部分转成string对象
value:要转String的char数组
offset:从数组的哪个索引开始转
count:转多少个
2.string(byte[]bytes,int offset,int length) —> 将byte数组的一部分转成String对象bytes:要转String的byte数组
offset:从数组的哪个索引开始转
length:转多少个
public static void main(String[] args) { /* 1.string(char[] value,int offset,int count) —> 将char数组的一部分转成string对象 alue:要转String的char数组 offset:从数组的哪个索引开始转 count:转多少个 */ char[] chars = {'a','b','c','d','e','f'}; String s1 = new String(chars,1,5); // 从索引1开始转5个 System.out.println("s1="+s1); /* 2.string(byte[]bytes,int offset,int length) —> 将byte数组的一部分转成String对象 bytes:要转String的byte数组 offset:从数组的哪个索引开始转 length:转多少个 */ byte[] bytes = {97,98,99,100,101}; String s2 = new String(bytes,0,4); System.out.println(s2); }
笔试题
题1
s1与s2地址值一样,s3内容是s1共享过来,但是s3是new出来的,会自己创造新的空间,所以会有新的空间
问1:Strings=new String("abc")共有几个对象?
2个,一个new本身,一个是"abc”
问2:Strings= new String("abc")共创建了几个对象?
1个或者2个,就看abc有没有提前创建出来了
如果之前没有提前创建abc,那么就会创建2个,先创建abc,再new
如果之前提前创建了abc了,那么String s = new String("abc"),就只创建了一个,因为abc不用单独再创建了,直接共享过来即可
String s1 = "abc"
String s2 = new String("abc")题2
总结
1.字符串拼接,如果等号右边是字符串字面值拼接,不会产生新对象
2.字符串拼接,如果等号右边有变量参数拼接,会产生新字符串对象
二、String常用方法
1.判断方法
boolean equals(String s) —> 比较字符串内容
boolean equalsIgnoreCase(String s) —> 比较字符串内容,忽略大小写示例
public static void main(String[] args) { String s1 = "abc"; String s2 = new String("abc"); String s3 = "Abc"; System.out.println(s1==s2); // 比较地址值 false System.out.println(s1.equals(s2));// 比较内容 true System.out.println(s3.equals(s1));// 比较内容 不忽略大小写 false System.out.println(s3.equalsIgnoreCase(s1));// 比较内容 忽略大小写 true }
练习
已知用户名和密码,请用程序实现模拟用户登录。总共给三次机会,登录成功与否,给出相应的提示步骤:
①先定义两个字符串,表示注册过的用户名和密码
②创建scanner对象,键盘录入用户名和密码
③比较,如果输入的用户名和密码跟已经注册过的用户名和密码内容一样,就登录成功,否则就登录失败public static void main(String[] args) { // ① 先定义两个字符串,表示注册过的用户名和密码 String username = "root"; String password = "954926928"; // ② 创建scanner对象,键盘录入用户名和密码 for (int i = 0; i < 3; i++) { Scanner sc = new Scanner(System.in); System.out.println("请您输入用户名"); String ans = sc.next(); // ③ 比较,如果输入的用户名和密码跟已经注册过的用户名和密码内容一样,就登录成功,否则就登录失败 if (ans.equals(username)) { System.out.println("请您输入用户密码"); String que = sc.next(); if (que.equals(password)) { System.out.println("登陆成功!"); break; } else { System.out.println("密码错误,请重新登录"); } } else { System.out.println("没有找到用户,请先注册账户"); } } }
用确定的值.equals,这样可以防止空指针
Objects中的equals方法,自带防止空指针
即使是两个指针都为null,也会判断成一样的
2.获取功能
① int length()->获取字符串长度
② String concat(Strings)->字符串拼接,返回新串儿
③ char charAt(int index)-> 根据索引获取对应的字符
④ int indexof(string s)->获取指定字符串在大字符串中第一次出现的索引位置
⑤ String substring(int beginIndex)->截取字符串,从指定索引开始截取到最后,返回新串儿
⑥ String substring(int beginIndex,int endIndex)->截取字符串,从beginIndex开始到endIndex结束,含头不含尾,返回新串儿
示例
public static void main(String[] args) { // ① int length()->获取字符串长度 System.out.println("一切都会好的".length()); // ② String concat(Strings)->字符串拼接,返回新串儿 String S1 = "一切都会好的"; String S2 = "我一直相信"; System.out.println(S1.concat(S2)); // ③ char charAt(int index)-> 根据索引获取对应的字符 System.out.println(S1.charAt(4)); // ④ int indexof(string s)->获取指定字符串在大字符串中第一次出现的索引位置 System.out.println(S1.concat(S2).indexOf("信")); // ⑤ String substring(int beginIndex)->截取字符串,从指定索引开始截取到最后,返回新串儿 System.out.println(S1.concat(S2).substring(2)); // ⑥ String substring(int beginIndex,int endIndex)->截取字符串,从beginIndex开始到endIndex结束,含头不含尾(括号左开右闭),返回新串儿 System.out.println(S1.concat(S2).substring(3,6)); System.out.println("——————————————————————————————————————"); for (int i = 0; i < S1.concat(S2).length(); i++) { System.out.println(S1.concat(S2).charAt(i)); } }
3.转换功能
1.char[] tocharArray() —> 将字符串转成char数组
2.byte[] getBytes() —> 将字符串转成byte数组
3.String replace(CharSequence c1,CharSequence c2) —> 替换字符
CharSequence —> String的接口
4.byte[] getBytes(String charsetName) —> 按照指定的编码将字符串转成byte数组示例:
public static void main(String[] args) throws UnsupportedEncodingException { // 1.char[] tocharArray() —> 将字符串转成char数组 String s = "abcdef"; char[] chars = s.toCharArray(); for (int i = 0; i < chars.length; i++) { System.out.println(chars[i]); } System.out.println("————————————————————"); // 2.byte[] getBytes() —> 将字符串转成byte数组 byte[] bytes = s.getBytes(); for (int i = 0; i < bytes.length; i++) { System.out.println(bytes[i]); } System.out.println("————————————————————"); // 3.String replace(CharSequence c1,CharSequence c2) —> 替换字符 CharSequence —> String的接口 System.out.println(s.replace("a","z")); System.out.println("————————————————————"); // 4.byte[] getBytes(String charsetName) —> 按照指定的编码将字符串转成byte数组 byte[] bytes1 = "一切都会好的".getBytes("utf-8"); for (int i = 0; i < bytes1.length; i++) { System.out.println(bytes1[i]); } }
练习
键盘录入一个字符串,统计该字符串中大写字母字符,小写字母字符,数字字符出现的次数(不考虑其他字符)
步骤:
1.创建scanner对象,键盘录入
2.定义三个变量,用来统计
3.调用next方法录入一个字符串,遍历字符串,将每一个字符拿出来
4.统计大写字母A-Z -> 65-90
比如:B -> 66 -> 在65-90之间,证明就是大写字母
5.统计小写字母
a-z -> 97-122
比如:b->98->在97-122之间,证明就是小写字母6.统计数字:
0-9 -> 48-57
比如:字符1->49->在48-57之间,证明就是数字7.将统计结果打印出来
package S57String; import java.util.Scanner; public class Demo168String8Practice { public static void main(String[] args) { // 1.创建scanner对象,键盘录入 Scanner sc = new Scanner(System.in); // 2.定义三个变量,用来统计 int big = 0; int small = 0; int number = 0; // 3.调用next方法录入一个字符串,遍历字符串,将每一个字符拿出来 String data = sc.next(); char[] chars = data.toCharArray(); for (int i = 0; i < chars.length; i++) { char num = chars[i]; // 4.统计大写字母 // A-Z -> 65-90 // 比如:B->66->在65-90之间,证明就是大写字母 if (num >= 'A' && num <= 'Z') { big++; } // 5.统计小写字母 // a-z-> 97-122 // 比如:b->98->在97-122之间,证明就是小写字母 if (num >= 'a' && num <= 'z') { small++; } // 6.统计数字: // 0-9 -> 48-57 // 比如:字符1T>49 ->在48-57之间,证明就是数字 if (num >= '0' && num <= '9') { number++; } } // 7.将统计结果打印出来 System.out.println("大写有:"+big); System.out.println("小写有:"+small); System.out.println("数字有:"+number); } }
4.分割功能
1.String[] split(String regex) —> 按照指定的规则分割字符串
注意:regex写的是正则表达式->,在正则表达式中代表任意一个字符
示例:
public class Demo169String9Cut { public static void main(String[] args) { String s = "abc,txt"; // 按照逗号进行分割 String[] split = s.split(","); for (int i = 0; i < split.length; i++) { System.out.println(split[i]); } }
按照.切割切不出来,需要用\\转义
5.其他功能
1.boolean contains(string s) —> 判断老串儿中是否包含指定的串儿
2.boolean endsWith(string s) —> 判断老串儿是否以指定的串儿结尾
3.boolean startsWith(string s) —> 判断老串儿是否以指定的串儿开头
4.string toLowerCase() —> 将字母转成小写
5.string toUpperCase() —> 将字母转成大写
6.string trim() —> 去掉字符串两端空格
示例:
public static void main(String[] args) { String s = "abcdefg"; // 1.boolean contains(string s) —> 判断老串儿中是否包含指定的串儿 System.out.println(s.contains("def")); // 2.boolean endsWith(string s) —> 判断老串儿是否以指定的串儿结尾 System.out.println(s.endsWith("fg")); // 3.boolean startsWith(string s) —> 判断老串儿是否以指定的串儿开头 System.out.println(s.startsWith("abcd")); // 4.string toLowerCase() —> 将字母转成小写 System.out.println(s.toLowerCase()); // 5.string toUpperCase() —> 将字母转成大写 System.out.println(s.toLowerCase().toUpperCase()); // 6.string trim() —> 去掉字符串两端空格,去不掉中间空格 s = " 一切都会好的 "; System.out.println(s.trim()); // 7.去掉所有空格 replace将空格进行替换 System.out.println("一起都会好的 我一直相信".replace(" ","")); }
三、总结
1.概述
代表的是字符串
2.特点
a.凡是带双引号的,都是String的对象
b.字符串是常量,他们的值在创建之后不能被更改
c.srring对象是不可变的,所以可以共享3.创建
a.String0
b.String(String s)
c.sring(char[] chars)
d.string(bytell bytes)e.string(char0] chars,int offset,int count)
chars代表被转的数组
ofset代表从数组的哪个索引开始转
count代表转多少个f.String(bytel] bytes,int offset,int count)
bytes代表被转的数组
offset代表从数组的哪个素引开始转count代表转多少个
4.方法
a.判断方法
① boolean equals(Object obj) -- 判断字符串内容是否一样
② boolean equalslgnoreCase(Strings) -- 判断字符串内容是否一样,忽略大小写
b.获取方法
① int length() -- 获取字符串长度
② Slring concal(slring s)-- 拼接字符串,返回新串
③ char charAt(int index)-- 根据索引获取对应的字符
④ int indexOfstrings) -- 获取指定字符在字符串中第一次出现的素引位置
⑤ String subString(int beginIndex) -- 从beginIndex开始截取字符串到最后
⑥ String substring(int beginindex,int endindex) -- 从beginIndex到endIndex截取字符串,含头不含尾c.转换方法
① char[] toCharArray() -- 将字符串转成char数组
② byte[] getBytes0 -- 将字符串转成byte数组
③ bytell getBytes(Sting charsetName) -- 按照指定的编码规则将字符串转成byte数组④ String replace(c1,c2) -- 将c1替换成c2
d.分割方法
① String[] split(string regex) -- 按照指定规则分割字符串
e.其他方法
① boolean contains(String s) -- 判断字符串是否包含指定的字符串内容
② boolean endsWith(string s) -- 判断字符串是否以指定的串儿结尾③ boolean startsWith(String s) -- 判断字符串是否以指定的串儿开头
④ String toLowerCase() -- 将字母转成小写
⑤ String toUpperCase() -- 将字母转成大写
⑥ String trim() -- 去掉字符串两端空格