学习09[常用类]
String类
例子:
-
代表字符串,使用一对“”引起来表示
-
是一个final类,不可被继承,代表不可变的字符序列
-
String实现了Serializable接口:表示字符串是支持序列化的(IO)
实现了Comparable接口:表示String可以比较大小
-
String内部定义了final char[] value用于储存字符串数据
-
通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串声明再字符串常量池中
String s1="abc";//字面量的定义方式String s2="abc"; -
字符串常量池中是不会存储相同内容的字符串:
使用String类的equals()比较,返回true的字符串
-
String代表了一个不可变的字符串序列,简称:不可变性,体现:
-
当对字符串重新赋值时,需要重写指定的内存区域赋值,不能使用原有的value进行赋值
String s1="abc";
String s2="abc";
s1="hello"; -
当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值
String s3="abc";
s3+="def";
System.out.println(s3);//abccdef -
当调用String的replace( )方法修改指定字符或字符串时,也需要重新指定内存区域赋值
String s4="abc";
String s5=s4.replace("a","m");
System.out.println(s4);//abc
System.out.println(s5);//mbc
-
String对象的创建
-
String的实例化方式:
-
通过字面量定义的方式
-
通过new+构造器的方式
//通过字面量定义的方式:
// 此时的s1和s2数据JavaEE声明在方法区中的字符串常量池中
String s1="javaEE";
String s2="javaEE";
//通过new+构造器的方式:
// 此时的s1和s2保存的地址值,是数据在堆空间中开辟空间以后对应的地址值
String s3=new String("javaEE");
String s4=new String("javaEE");
System.out.println(s1 == s2);//true
System.out.println(s1 == s3);//false
System.out.println(s1 == s4);//false
System.out.println(s3 == s4);//false
Person p1=new Person("Tom",12);
Person p2=new Person("Tom",12);
System.out.println(p1.name.equals(p2.name));//true
System.out.println(p1.name==p2.name);//true
-
面试题:
String s = new String("abc");方式创建对象,在内存中创建了几个对象?
两个:一个是在堆空间中new结构,另一个是char[ ]对应的常量池中的数据:“abc”
String s1="JavaEE";
String s2="hadoop";//基本
String s3="JavaEEhadoop";
String s4="JavaEE"+"hadoop";
String s5=s1+"hadoop";
String s6="JavaEE"+s2;
String s7=s1+s2;
System.out.println(s3 ==s4);//true
System.out.println(s3 =s5);//false
System.out.println(s3 =s6);//false
System.out.println(s3 =s7);//false
System.out.println(s5 =s6);//false
System.out.println(s5 =s7);//false
System.out.println(s6 =s7);//false
-
结论:
-
常量与常量的拼接结果在常量池,且常量池中不会存在相同内容的常量
-
只要其中有一个变量,结果就在堆中
-
如果拼接的结果调用intern()方法,返回值就在常量池中
String s8=s5.intern();//返回值得到的s8是常量池中已经存在的“JavaEEhadoop”
System.out.println(s3==s8);//true
补充:final
-
面试题:Java值传递
jdk1.6:字符串常量池存储在方法区(永久区)
jdk1.7:字符串常量池存储在堆空间
jdk1.8:字符串常量池存储在方法区(元空间)
String常用方法1
-
int length()
返回字符串的长度:return value.length
-
char charAt(int index)
返回某索引处的字符:return value[index]
String s1="helloworld";
System.out.println(s1.length());//10
System.out.println(s1.charAt(0));//h
System.out.println(s1.charAt(9));//d
System.out.println(s1.charAt(10));//越界注意下标长度不要越界
-
boolean isEmpty()
判断是否为空字符串:return value.length==0
(结果为true/false)
String s2="";
System.out.println(s2.isEmpty());//true -
String toLowerCase()
使用默认语言环境,将String中所有字符转换为小写
String s1="HelloWorld";
String s2=s1.toLowerCase(Locale.ROOT);//返回值接收为s2
System.out.println(s1);//HelloWorld,s1不可变,仍为原来字符串
System.out.println(s2);
//helloworld,改成小写以后字符串 -
String toUpperCase()
使用默认语言环境,将String中所有字符转换为大写
-
String trim()
返回字符串的副本,忽略前导空白和尾部空白(中间空格不变)
String s3=" he llo world ";
System.out.println("--"+s3+"--");
//-- he llo world --
System.out.println("--"+s3.trim()+"--");
//--he llo world-- -
boolean equals(Object obj)
比较字符串内容是否相同
-
boolean equalsIgnoreCase(String anotherString)
与equals方法类似,忽略大小写
String s1="HelloWorld";
String s2="helloworld";
System.out.println(s1.equals(s2));//false
System.out.println(s1.equalsIgnoreCase(s2));//true -
String concat(String str)
将指定的字符串连接到此字符串的结尾,等价于用“+”
String s3="abc";
String s4 = s3.concat("def");
System.out.println(s4);//abcdef -
int compareTo(String anotherString)
比较两个字符串的大小
String s5="abc";
String s6=new String("abe");
System.out.println(s5.compareTo(s6));//-2
//a是97,e是101
//涉及到字符串排序 -
String substring(int beginIndex)
返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个字符串
取出一个子字符串
String s7="北京尚硅谷教育";
String s8 = s7.substring(2);
System.out.println(s7);
//北京尚硅谷教育
System.out.println(s8);
//尚硅谷教育 -
String substring(int beginIndex,int endIndex)
返回一个新的字符串,它是此字符串的从beginIndex开始截取到endIndex(不包含)的一个字符串
[左闭右开)
String s7="北京尚硅谷教育";
String s9 = s7.substring(2, 5);//尚硅谷
String常用方法2
-
boolean endsWith(String suffix)
测试此字符串是否以指定的后缀结束
String str1="helloworld";
boolean b1=str1.endsWith("ld");
System.out.println(b1);//true -
boolean startsWith(String prefix)
测试此字符串是否以指定的前缀开始
String str1="helloworld";
boolean b2= str1.startsWith("He");
System.out.println(b2);//false -
boolean startsWith(String prefix,int toffset)
测试此字符串从指定索引开始的字符串是否以指定的前缀开始
从第2个开始,以"ll"开始(√)
String str1="helloworld";
boolean b3 = str1.startsWith("ll",2);
System.out.println(b3);//true
-
boolean contains(CharSequence s )
当且仅当此字符串包含指定的char值序列时,返回true
String str1="helloworld";
String str2="wo";
System.out.println(str1.contains(str2));//true -
int indexOf(String str)
返回指定子字符串在此字符串中第一次出现处的索引
String str1="helloworld";
System.out.println(str1.indexOf("lo"));//3
System.out.println(str1.indexOf("lol"));//-1:未找到的规定返回-1 -
int indexOf(String str, int fromIndex)
返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
从5开始找
String str1="helloworld";
System.out.println(str1.indexOf("lo",5));//-1 -
int lastIndexOf(String str)
返回指定子字符串在此字符串中最右边出现处的索引
0 1 2 3 4 5 6 7 8 9 10依旧从前往后数
h e l l o r w o r l d
String str3="hellorworld";
System.out.println(str3.lastIndexOf("or"));//7 -
int lastIndexOf(String str, int fromIndex)
返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索
0 1 2 3 4 5 6|7 8 9 10
h e l l o r w o r l d
String str3="hellorworld";
System.out.println(str3.lastIndexOf("or",6));//4
-
什么情况下,indexOf(str)和lastIndexOf(str)返回值相同?
情况一:存在唯一的一个str
情况二:不存在str
String常用方法3
替换-------------------------------------------------
-
String replace(char oldChar,char newChar)
返回一个新的字符串,他是通过newChar替换此字符串中出现的所有oldChar得到的
全改
String str1="北京尚硅谷教育北京";
String str2 =str1.replace('北', '东');
System.out.println(str1);//北京尚硅谷教育北京
System.out.println(str2);//东京尚硅谷教育东京 -
String replace(CharSequence target, CharSequence replacement)
使用指定的字面值替换序列替换此字符串所用匹配字面值目标序列的字符串
String str1="北京尚硅谷教育北京";
String str3 = str1.replace("北京", "上海");
//上海尚硅谷教育上海
-
String replaceAll(String regex:正则, String replacement)
使用给定的replacement替换此字符串所有匹配给定的正则表达式的子字符串
-
String replaceFirst(String regex, String replacement)
使用给定的replacement替换此字符串匹配给定的正则表达式的第一个子字符串
匹配(了解)--------------------------------------------
-
boolean matches(String regex)
告知此字符串是否匹配给定的正则表达式
切片(了解)--------------------------------------------
-
String[] split(String regex)
根据给定正则表达式的匹配拆分此字符串
-
String[] split(String regex, int limit)
根据匹配给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中
复习:
1、String转换基本数据类型、包装类
涉及到String类与其他结构之间的转换
String与基本数据类型和包装类之间的转换
-
String---->基本数据类型、包装类:
调用包装类的静态方法:parseXxx(str)
String str1="123";
int num=Integer.parseInt(str1); -
基本数据类型、包装类---->String
调用String重载的valueOf(xxx)
String str2 = String.valueOf(num);//"123"
//或
String str2=num+"";
2、String与字符数组转换
String与char[]之间的转换
-
String---->char[]:调用String的toCharArray()方法
str.toCharArray()
char[] charArray =
str2.toCharArray();
for (int i = 0; i <
charArray.length; i++) { System.out.println(charArray[i]);//输出charArray数组元素
}
-
char[]---->String:调用String的构造器
new String(arr);char[] arr=new char[]{'h','e','l','l','o'};
String str3 = new String(arr);
//new String(arr);
System.out.println(arr);//hello
3、String与byte[]之间的转换
-
String---->byte[],编码
调用String的getBytes()方法
String str1="abc123";
byte[] bytes = str1.getBytes();
System.out.println(Arrays.toString(bytes));
//[97, 98, 99, 49, 50, 51]
编码:字符串---->字节(看得懂-->看不懂)
解码:编码的逆过程 字节---->字符串
-
byte[]---->String,解码
调用String的构造器
String str2 = new String(bytes);
System.out.println(str2);//abc123中国
String str3 = new String(gbks);
System.out.println(str3);//abc123�й�出现乱码:解析时没有用gbk,编码集和解码集不一致
指定后没有乱码:
String gbk = new String(gbks, "gbk");
System.out.println(gbk);//abc123中国
说明:解码时,要求解码使用的字符集必须与编码时使用的字符集一致
StringBuffer类
关于 StringBuffer和 StringBuilder的使用
String、StringBuffer、StringBuilder三者异同:
String:不可变的字符序列;底层使用char[]存储
StringBuffer:可变的字符序列,线程安全的,效率低;底层使用char[]存储
StringBuilder:可变的字符序列,jdk5.0新增的,线程不安全的,效率高;底层使用char[]存储
源码分析:
String str=new String();//new char[0];
String str1=new String("abc"); //new char[]{'a','b','c'};
StringBuffer sb1=new StringBuffer(); //char[] value=new char[16];
相当于底层创建了一个长度为16的数组
sb1.oppend('a');//value[0]='a';
//相当于value首位置赋值为a,
sb1.oppend('b');//value[1]='b';
可变:可以在现有的加
StringBuffer str2=new StringBuffer("abc");//char[] value=new char["abc".length()+16]
每次造完后会额外空出16个
问题1:
StringBuffer str2=new StringBuffer();
System.out.println(sb1.length());//0
//
StringBuffer str2=new StringBuffer("abc");
System.out.println(sb1.length());//3
问题2:
扩容问题:如果要添加的数据底层数据盛不下了,那就需要扩容底层数组
默认情况下,扩容为原来的2倍+2,同时将原有数组的元素复制到新的数组中
指导意义:开发中使用:StringBuffer(int capacity)或StringBuilder(int capacity),指定容量,避免扩容复制
StringBuffer类的常用方法
-
StringBuffer append(xxx):
提供了很多的append()方法,用于进行字符串拼接
方法链:s.append().append().append()
StringBuffer s1=new StringBuffer("abc");
s1.append(1);
s1.append("1");
System.out.println(s1);//abc11 -
StringBuffer delete(int start,int end);
删除指定位置的内容
左闭右开
s1.delete(2,4);
System.out.println(s1);//ab1 -
StringBuffer replace(int start,int end,String str):
把[start,end)左闭右开位置替换为str
s1.replace(2,4,"hello");
System.out.println(s1);
//abhello1 -
StringBuffer insert(int offset,xxx):
在指定位置插入xxx
s1.insert(2,false);
System.out.println(s1);
//abfalsec11 -
StringBuffer reverse():
把当前字符序列逆转
s1.reverse();
System.out.println(s1);//11cba -
public int indexOf(String str)
-
public String substring(int start,int end)
返回一个从start开始到end结束的左闭右开的子字符串
原字符串s1没有变化
String s2 = s1.substring(2, 4);
System.out.println(s1.length());//5
System.out.println(s2);//cb -
public int length()
-
public char charAt(int n)
-
public void setChatAt(int n ,char ch)
总结:
增:append(xxx)
删:delete(int start,int end)
改:setChatAt(int n ,char ch)/replace(int start,int end,String str)
查:charAt(int n)
插:insert(int offset,xxx)
长度:length();
遍历:for()+charAt()/toString()
String、StringBuffer、StringBuilder三者效率:
StringBuilder>StringBuffer>String
String、StringBuffer、StringBuilder之间的转换:
-
String--->StringBuffer、StringBuilder:
调用StringBuffer、StringBuilder的构造器
new StringBuffer(String str);
-
StringBuffer、StringBuilder--->String:
①调用String的构造器
②StringBuffer、StringBuilder的toString()方法
JDK8之前的日期时间API测试
-
System类中的currentTimeMillis()
用来返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差
称为时间戳
此方法适于计算时间差
long time = System.currentTimeMillis();
System.out.println(time);//1633966657021
-
Date类
-
两个构造器的使用:java.util.Date类
-
构造器一:Date();
创建一个对应当前时间的Date对象
Date date1 = new Date();
System.out.println(date1.toString());
//Mon Oct 11 23:50:11 CST 2021
-
构造器二:创建指定毫秒数的Date对象
1633967701698L
Date date2 = new Date(1633967701698l);
System.out.println(date2.toString());
//Mon Oct 11 23:55:01 CST 2021
还有|------java.sql.Date类
-
两个方法的使用
-
toString():显示当前的年月日时分秒
-
getTime():获取当前Date对象的毫秒数(时间戳)
System.out.println(date1.getTime());//1633967701698
-
java.sql.Date对应着数据库中的日期类型的变量
如何实例化:创建java.sql.Date对象
java.sql.Date date3 = new java.sql.Date(345678368494L);
System.out.println(date3);
//1980-12-15只打印年月日
-
sql.Date----->util.Date对象:多态
-
util.Date----->sql.Date对象p470
情况一:强转√
Date date4=new java.sql.Date(5678976534567L);
java.sql.Date date5=(java.sql.Date)date4;
情况二:
Date date6=new Date();
java.sql.Date date7=new java.sql.Date(date6.getTime());
//用getTime()方法找到time,把毫秒数扔到构造器里作为参数
习题
String类
例子:
-
代表字符串,使用一对“”引起来表示
-
是一个final类,不可被继承,代表不可变的字符序列
-
String实现了Serializable接口:表示字符串是支持序列化的(IO)
实现了Comparable接口:表示String可以比较大小
-
String内部定义了final char[] value用于储存字符串数据
-
通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串声明再字符串常量池中
String s1="abc";//字面量的定义方式String s2="abc"; -
字符串常量池中是不会存储相同内容的字符串:
使用String类的equals()比较,返回true的字符串
-
String代表了一个不可变的字符串序列,简称:不可变性,体现:
-
当对字符串重新赋值时,需要重写指定的内存区域赋值,不能使用原有的value进行赋值
String s1="abc";
String s2="abc";
s1="hello"; -
当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值
String s3="abc";
s3+="def";
System.out.println(s3);//abccdef -
当调用String的replace( )方法修改指定字符或字符串时,也需要重新指定内存区域赋值
String s4="abc";
String s5=s4.replace("a","m");
System.out.println(s4);//abc
System.out.println(s5);//mbc
-
String对象的创建
-
String的实例化方式:
-
通过字面量定义的方式
-
通过new+构造器的方式
//通过字面量定义的方式:
// 此时的s1和s2数据JavaEE声明在方法区中的字符串常量池中
String s1="javaEE";
String s2="javaEE";
//通过new+构造器的方式:
// 此时的s1和s2保存的地址值,是数据在堆空间中开辟空间以后对应的地址值
String s3=new String("javaEE");
String s4=new String("javaEE");
System.out.println(s1 == s2);//true
System.out.println(s1 == s3);//false
System.out.println(s1 == s4);//false
System.out.println(s3 == s4);//false
Person p1=new Person("Tom",12);
Person p2=new Person("Tom",12);
System.out.println(p1.name.equals(p2.name));//true
System.out.println(p1.name==p2.name);//true
-
面试题:
String s = new String("abc");方式创建对象,在内存中创建了几个对象?
两个:一个是在堆空间中new结构,另一个是char[ ]对应的常量池中的数据:“abc”
String s1="JavaEE";
String s2="hadoop";//基本
String s3="JavaEEhadoop";
String s4="JavaEE"+"hadoop";
String s5=s1+"hadoop";
String s6="JavaEE"+s2;
String s7=s1+s2;
System.out.println(s3 ==s4);//true
System.out.println(s3 =s5);//false
System.out.println(s3 =s6);//false
System.out.println(s3 =s7);//false
System.out.println(s5 =s6);//false
System.out.println(s5 =s7);//false
System.out.println(s6 =s7);//false
-
结论:
-
常量与常量的拼接结果在常量池,且常量池中不会存在相同内容的常量
-
只要其中有一个变量,结果就在堆中
-
如果拼接的结果调用intern()方法,返回值就在常量池中
String s8=s5.intern();//返回值得到的s8是常量池中已经存在的“JavaEEhadoop”
System.out.println(s3==s8);//true
补充:final
-
面试题:Java值传递
jdk1.6:字符串常量池存储在方法区(永久区)
jdk1.7:字符串常量池存储在堆空间
jdk1.8:字符串常量池存储在方法区(元空间)
String常用方法1
-
int length()
返回字符串的长度:return value.length
-
char charAt(int index)
返回某索引处的字符:return value[index]
String s1="helloworld";
System.out.println(s1.length());//10
System.out.println(s1.charAt(0));//h
System.out.println(s1.charAt(9));//d
System.out.println(s1.charAt(10));//越界注意下标长度不要越界
-
boolean isEmpty()
判断是否为空字符串:return value.length==0
(结果为true/false)
String s2="";
System.out.println(s2.isEmpty());//true -
String toLowerCase()
使用默认语言环境,将String中所有字符转换为小写
String s1="HelloWorld";
String s2=s1.toLowerCase(Locale.ROOT);//返回值接收为s2
System.out.println(s1);//HelloWorld,s1不可变,仍为原来字符串
System.out.println(s2);
//helloworld,改成小写以后字符串 -
String toUpperCase()
使用默认语言环境,将String中所有字符转换为大写
-
String trim()
返回字符串的副本,忽略前导空白和尾部空白(中间空格不变)
String s3=" he llo world ";
System.out.println("--"+s3+"--");
//-- he llo world --
System.out.println("--"+s3.trim()+"--");
//--he llo world-- -
boolean equals(Object obj)
比较字符串内容是否相同
-
boolean equalsIgnoreCase(String anotherString)
与equals方法类似,忽略大小写
String s1="HelloWorld";
String s2="helloworld";
System.out.println(s1.equals(s2));//false
System.out.println(s1.equalsIgnoreCase(s2));//true -
String concat(String str)
将指定的字符串连接到此字符串的结尾,等价于用“+”
String s3="abc";
String s4 = s3.concat("def");
System.out.println(s4);//abcdef -
int compareTo(String anotherString)
比较两个字符串的大小
String s5="abc";
String s6=new String("abe");
System.out.println(s5.compareTo(s6));//-2
//a是97,e是101
//涉及到字符串排序 -
String substring(int beginIndex)
返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个字符串
取出一个子字符串
String s7="北京尚硅谷教育";
String s8 = s7.substring(2);
System.out.println(s7);
//北京尚硅谷教育
System.out.println(s8);
//尚硅谷教育 -
String substring(int beginIndex,int endIndex)
返回一个新的字符串,它是此字符串的从beginIndex开始截取到endIndex(不包含)的一个字符串
[左闭右开)
String s7="北京尚硅谷教育";
String s9 = s7.substring(2, 5);//尚硅谷
String常用方法2
-
boolean endsWith(String suffix)
测试此字符串是否以指定的后缀结束
String str1="helloworld";
boolean b1=str1.endsWith("ld");
System.out.println(b1);//true -
boolean startsWith(String prefix)
测试此字符串是否以指定的前缀开始
String str1="helloworld";
boolean b2= str1.startsWith("He");
System.out.println(b2);//false -
boolean startsWith(String prefix,int toffset)
测试此字符串从指定索引开始的字符串是否以指定的前缀开始
从第2个开始,以"ll"开始(√)
String str1="helloworld";
boolean b3 = str1.startsWith("ll",2);
System.out.println(b3);//true
-
boolean contains(CharSequence s )
当且仅当此字符串包含指定的char值序列时,返回true
String str1="helloworld";
String str2="wo";
System.out.println(str1.contains(str2));//true -
int indexOf(String str)
返回指定子字符串在此字符串中第一次出现处的索引
String str1="helloworld";
System.out.println(str1.indexOf("lo"));//3
System.out.println(str1.indexOf("lol"));//-1:未找到的规定返回-1 -
int indexOf(String str, int fromIndex)
返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
从5开始找
String str1="helloworld";
System.out.println(str1.indexOf("lo",5));//-1 -
int lastIndexOf(String str)
返回指定子字符串在此字符串中最右边出现处的索引
0 1 2 3 4 5 6 7 8 9 10依旧从前往后数
h e l l o r w o r l d
String str3="hellorworld";
System.out.println(str3.lastIndexOf("or"));//7 -
int lastIndexOf(String str, int fromIndex)
返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索
0 1 2 3 4 5 6|7 8 9 10
h e l l o r w o r l d
String str3="hellorworld";
System.out.println(str3.lastIndexOf("or",6));//4
-
什么情况下,indexOf(str)和lastIndexOf(str)返回值相同?
情况一:存在唯一的一个str
情况二:不存在str
String常用方法3
替换-------------------------------------------------
-
String replace(char oldChar,char newChar)
返回一个新的字符串,他是通过newChar替换此字符串中出现的所有oldChar得到的
全改
String str1="北京尚硅谷教育北京";
String str2 =str1.replace('北', '东');
System.out.println(str1);//北京尚硅谷教育北京
System.out.println(str2);//东京尚硅谷教育东京 -
String replace(CharSequence target, CharSequence replacement)
使用指定的字面值替换序列替换此字符串所用匹配字面值目标序列的字符串
String str1="北京尚硅谷教育北京";
String str3 = str1.replace("北京", "上海");
//上海尚硅谷教育上海
-
String replaceAll(String regex:正则, String replacement)
使用给定的replacement替换此字符串所有匹配给定的正则表达式的子字符串
-
String replaceFirst(String regex, String replacement)
使用给定的replacement替换此字符串匹配给定的正则表达式的第一个子字符串
匹配(了解)--------------------------------------------
-
boolean matches(String regex)
告知此字符串是否匹配给定的正则表达式
切片(了解)--------------------------------------------
-
String[] split(String regex)
根据给定正则表达式的匹配拆分此字符串
-
String[] split(String regex, int limit)
根据匹配给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中
复习:
1、String转换基本数据类型、包装类
涉及到String类与其他结构之间的转换
String与基本数据类型和包装类之间的转换
-
String---->基本数据类型、包装类:
调用包装类的静态方法:parseXxx(str)
String str1="123";
int num=Integer.parseInt(str1); -
基本数据类型、包装类---->String
调用String重载的valueOf(xxx)
String str2 = String.valueOf(num);//"123"
//或
String str2=num+"";
2、String与字符数组转换
String与char[]之间的转换
-
String---->char[]:调用String的toCharArray()方法
str.toCharArray()
char[] charArray =
str2.toCharArray();
for (int i = 0; i <
charArray.length; i++) { System.out.println(charArray[i]);//输出charArray数组元素
}
-
char[]---->String:调用String的构造器
new String(arr);char[] arr=new char[]{'h','e','l','l','o'};
String str3 = new String(arr);
//new String(arr);
System.out.println(arr);//hello
3、String与byte[]之间的转换
-
String---->byte[],编码
调用String的getBytes()方法
String str1="abc123";
byte[] bytes = str1.getBytes();
System.out.println(Arrays.toString(bytes));
//[97, 98, 99, 49, 50, 51]
编码:字符串---->字节(看得懂-->看不懂)
解码:编码的逆过程 字节---->字符串
-
byte[]---->String,解码
调用String的构造器
String str2 = new String(bytes);
System.out.println(str2);//abc123中国
String str3 = new String(gbks);
System.out.println(str3);//abc123�й�出现乱码:解析时没有用gbk,编码集和解码集不一致
指定后没有乱码:
String gbk = new String(gbks, "gbk");
System.out.println(gbk);//abc123中国
说明:解码时,要求解码使用的字符集必须与编码时使用的字符集一致
StringBuffer类
关于 StringBuffer和 StringBuilder的使用
String、StringBuffer、StringBuilder三者异同:
String:不可变的字符序列;底层使用char[]存储
StringBuffer:可变的字符序列,线程安全的,效率低;底层使用char[]存储
StringBuilder:可变的字符序列,jdk5.0新增的,线程不安全的,效率高;底层使用char[]存储
源码分析:
String str=new String();//new char[0];
String str1=new String("abc"); //new char[]{'a','b','c'};
StringBuffer sb1=new StringBuffer(); //char[] value=new char[16];
相当于底层创建了一个长度为16的数组
sb1.oppend('a');//value[0]='a';
//相当于value首位置赋值为a,
sb1.oppend('b');//value[1]='b';
可变:可以在现有的加
StringBuffer str2=new StringBuffer("abc");//char[] value=new char["abc".length()+16]
每次造完后会额外空出16个
问题1:
StringBuffer str2=new StringBuffer();
System.out.println(sb1.length());//0
//
StringBuffer str2=new StringBuffer("abc");
System.out.println(sb1.length());//3
问题2:
扩容问题:如果要添加的数据底层数据盛不下了,那就需要扩容底层数组
默认情况下,扩容为原来的2倍+2,同时将原有数组的元素复制到新的数组中
指导意义:开发中使用:StringBuffer(int capacity)或StringBuilder(int capacity),指定容量,避免扩容复制
StringBuffer类的常用方法
-
StringBuffer append(xxx):
提供了很多的append()方法,用于进行字符串拼接
方法链:s.append().append().append()
StringBuffer s1=new StringBuffer("abc");
s1.append(1);
s1.append("1");
System.out.println(s1);//abc11 -
StringBuffer delete(int start,int end);
删除指定位置的内容
左闭右开
s1.delete(2,4);
System.out.println(s1);//ab1 -
StringBuffer replace(int start,int end,String str):
把[start,end)左闭右开位置替换为str
s1.replace(2,4,"hello");
System.out.println(s1);
//abhello1 -
StringBuffer insert(int offset,xxx):
在指定位置插入xxx
s1.insert(2,false);
System.out.println(s1);
//abfalsec11 -
StringBuffer reverse():
把当前字符序列逆转
s1.reverse();
System.out.println(s1);//11cba -
public int indexOf(String str)
-
public String substring(int start,int end)
返回一个从start开始到end结束的左闭右开的子字符串
原字符串s1没有变化
String s2 = s1.substring(2, 4);
System.out.println(s1.length());//5
System.out.println(s2);//cb -
public int length()
-
public char charAt(int n)
-
public void setChatAt(int n ,char ch)
总结:
增:append(xxx)
删:delete(int start,int end)
改:setChatAt(int n ,char ch)/replace(int start,int end,String str)
查:charAt(int n)
插:insert(int offset,xxx)
长度:length();
遍历:for()+charAt()/toString()
String、StringBuffer、StringBuilder三者效率:
StringBuilder>StringBuffer>String
String、StringBuffer、StringBuilder之间的转换:
-
String--->StringBuffer、StringBuilder:
调用StringBuffer、StringBuilder的构造器
new StringBuffer(String str);
-
StringBuffer、StringBuilder--->String:
①调用String的构造器
②StringBuffer、StringBuilder的toString()方法
JDK8之前的日期时间API测试
-
System类中的currentTimeMillis()
用来返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差
称为时间戳
此方法适于计算时间差
long time = System.currentTimeMillis();
System.out.println(time);//1633966657021
-
Date类
-
两个构造器的使用:java.util.Date类
-
构造器一:Date();
创建一个对应当前时间的Date对象
Date date1 = new Date();
System.out.println(date1.toString());
//Mon Oct 11 23:50:11 CST 2021
-
构造器二:创建指定毫秒数的Date对象
1633967701698L
Date date2 = new Date(1633967701698l);
System.out.println(date2.toString());
//Mon Oct 11 23:55:01 CST 2021
还有|------java.sql.Date类
-
两个方法的使用
-
toString():显示当前的年月日时分秒
-
getTime():获取当前Date对象的毫秒数(时间戳)
System.out.println(date1.getTime());//1633967701698
-
java.sql.Date对应着数据库中的日期类型的变量
如何实例化:创建java.sql.Date对象
java.sql.Date date3 = new java.sql.Date(345678368494L);
System.out.println(date3);
//1980-12-15只打印年月日
-
sql.Date----->util.Date对象:多态
-
util.Date----->sql.Date对象p470
情况一:强转√
Date date4=new java.sql.Date(5678976534567L);
java.sql.Date date5=(java.sql.Date)date4;
情况二:
Date date6=new Date();
java.sql.Date date7=new java.sql.Date(date6.getTime());
//用getTime()方法找到time,把毫秒数扔到构造器里作为参数
习题
String类
例子:
-
代表字符串,使用一对“”引起来表示
-
是一个final类,不可被继承,代表不可变的字符序列
-
String实现了Serializable接口:表示字符串是支持序列化的(IO)
实现了Comparable接口:表示String可以比较大小
-
String内部定义了final char[] value用于储存字符串数据
-
通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串声明再字符串常量池中
String s1="abc";//字面量的定义方式String s2="abc"; -
字符串常量池中是不会存储相同内容的字符串:
使用String类的equals()比较,返回true的字符串
-
String代表了一个不可变的字符串序列,简称:不可变性,体现:
-
当对字符串重新赋值时,需要重写指定的内存区域赋值,不能使用原有的value进行赋值
String s1="abc";
String s2="abc";
s1="hello"; -
当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值
String s3="abc";
s3+="def";
System.out.println(s3);//abccdef -
当调用String的replace( )方法修改指定字符或字符串时,也需要重新指定内存区域赋值
String s4="abc";
String s5=s4.replace("a","m");
System.out.println(s4);//abc
System.out.println(s5);//mbc
-
String对象的创建
-
String的实例化方式:
-
通过字面量定义的方式
-
通过new+构造器的方式
//通过字面量定义的方式:
// 此时的s1和s2数据JavaEE声明在方法区中的字符串常量池中
String s1="javaEE";
String s2="javaEE";
//通过new+构造器的方式:
// 此时的s1和s2保存的地址值,是数据在堆空间中开辟空间以后对应的地址值
String s3=new String("javaEE");
String s4=new String("javaEE");
System.out.println(s1 == s2);//true
System.out.println(s1 == s3);//false
System.out.println(s1 == s4);//false
System.out.println(s3 == s4);//false
Person p1=new Person("Tom",12);
Person p2=new Person("Tom",12);
System.out.println(p1.name.equals(p2.name));//true
System.out.println(p1.name==p2.name);//true
-
面试题:
String s = new String("abc");方式创建对象,在内存中创建了几个对象?
两个:一个是在堆空间中new结构,另一个是char[ ]对应的常量池中的数据:“abc”
String s1="JavaEE";
String s2="hadoop";//基本
String s3="JavaEEhadoop";
String s4="JavaEE"+"hadoop";
String s5=s1+"hadoop";
String s6="JavaEE"+s2;
String s7=s1+s2;
System.out.println(s3 ==s4);//true
System.out.println(s3 =s5);//false
System.out.println(s3 =s6);//false
System.out.println(s3 =s7);//false
System.out.println(s5 =s6);//false
System.out.println(s5 =s7);//false
System.out.println(s6 =s7);//false
-
结论:
-
常量与常量的拼接结果在常量池,且常量池中不会存在相同内容的常量
-
只要其中有一个变量,结果就在堆中
-
如果拼接的结果调用intern()方法,返回值就在常量池中
String s8=s5.intern();//返回值得到的s8是常量池中已经存在的“JavaEEhadoop”
System.out.println(s3==s8);//true
补充:final
-
面试题:Java值传递
jdk1.6:字符串常量池存储在方法区(永久区)
jdk1.7:字符串常量池存储在堆空间
jdk1.8:字符串常量池存储在方法区(元空间)
String常用方法1
-
int length()
返回字符串的长度:return value.length
-
char charAt(int index)
返回某索引处的字符:return value[index]
String s1="helloworld";
System.out.println(s1.length());//10
System.out.println(s1.charAt(0));//h
System.out.println(s1.charAt(9));//d
System.out.println(s1.charAt(10));//越界注意下标长度不要越界
-
boolean isEmpty()
判断是否为空字符串:return value.length==0
(结果为true/false)
String s2="";
System.out.println(s2.isEmpty());//true -
String toLowerCase()
使用默认语言环境,将String中所有字符转换为小写
String s1="HelloWorld";
String s2=s1.toLowerCase(Locale.ROOT);//返回值接收为s2
System.out.println(s1);//HelloWorld,s1不可变,仍为原来字符串
System.out.println(s2);
//helloworld,改成小写以后字符串 -
String toUpperCase()
使用默认语言环境,将String中所有字符转换为大写
-
String trim()
返回字符串的副本,忽略前导空白和尾部空白(中间空格不变)
String s3=" he llo world ";
System.out.println("--"+s3+"--");
//-- he llo world --
System.out.println("--"+s3.trim()+"--");
//--he llo world-- -
boolean equals(Object obj)
比较字符串内容是否相同
-
boolean equalsIgnoreCase(String anotherString)
与equals方法类似,忽略大小写
String s1="HelloWorld";
String s2="helloworld";
System.out.println(s1.equals(s2));//false
System.out.println(s1.equalsIgnoreCase(s2));//true -
String concat(String str)
将指定的字符串连接到此字符串的结尾,等价于用“+”
String s3="abc";
String s4 = s3.concat("def");
System.out.println(s4);//abcdef -
int compareTo(String anotherString)
比较两个字符串的大小
String s5="abc";
String s6=new String("abe");
System.out.println(s5.compareTo(s6));//-2
//a是97,e是101
//涉及到字符串排序 -
String substring(int beginIndex)
返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个字符串
取出一个子字符串
String s7="北京尚硅谷教育";
String s8 = s7.substring(2);
System.out.println(s7);
//北京尚硅谷教育
System.out.println(s8);
//尚硅谷教育 -
String substring(int beginIndex,int endIndex)
返回一个新的字符串,它是此字符串的从beginIndex开始截取到endIndex(不包含)的一个字符串
[左闭右开)
String s7="北京尚硅谷教育";
String s9 = s7.substring(2, 5);//尚硅谷
String常用方法2
-
boolean endsWith(String suffix)
测试此字符串是否以指定的后缀结束
String str1="helloworld";
boolean b1=str1.endsWith("ld");
System.out.println(b1);//true -
boolean startsWith(String prefix)
测试此字符串是否以指定的前缀开始
String str1="helloworld";
boolean b2= str1.startsWith("He");
System.out.println(b2);//false -
boolean startsWith(String prefix,int toffset)
测试此字符串从指定索引开始的字符串是否以指定的前缀开始
从第2个开始,以"ll"开始(√)
String str1="helloworld";
boolean b3 = str1.startsWith("ll",2);
System.out.println(b3);//true
-
boolean contains(CharSequence s )
当且仅当此字符串包含指定的char值序列时,返回true
String str1="helloworld";
String str2="wo";
System.out.println(str1.contains(str2));//true -
int indexOf(String str)
返回指定子字符串在此字符串中第一次出现处的索引
String str1="helloworld";
System.out.println(str1.indexOf("lo"));//3
System.out.println(str1.indexOf("lol"));//-1:未找到的规定返回-1 -
int indexOf(String str, int fromIndex)
返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
从5开始找
String str1="helloworld";
System.out.println(str1.indexOf("lo",5));//-1 -
int lastIndexOf(String str)
返回指定子字符串在此字符串中最右边出现处的索引
0 1 2 3 4 5 6 7 8 9 10依旧从前往后数
h e l l o r w o r l d
String str3="hellorworld";
System.out.println(str3.lastIndexOf("or"));//7 -
int lastIndexOf(String str, int fromIndex)
返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索
0 1 2 3 4 5 6|7 8 9 10
h e l l o r w o r l d
String str3="hellorworld";
System.out.println(str3.lastIndexOf("or",6));//4
-
什么情况下,indexOf(str)和lastIndexOf(str)返回值相同?
情况一:存在唯一的一个str
情况二:不存在str
String常用方法3
替换-------------------------------------------------
-
String replace(char oldChar,char newChar)
返回一个新的字符串,他是通过newChar替换此字符串中出现的所有oldChar得到的
全改
String str1="北京尚硅谷教育北京";
String str2 =str1.replace('北', '东');
System.out.println(str1);//北京尚硅谷教育北京
System.out.println(str2);//东京尚硅谷教育东京 -
String replace(CharSequence target, CharSequence replacement)
使用指定的字面值替换序列替换此字符串所用匹配字面值目标序列的字符串
String str1="北京尚硅谷教育北京";
String str3 = str1.replace("北京", "上海");
//上海尚硅谷教育上海
-
String replaceAll(String regex:正则, String replacement)
使用给定的replacement替换此字符串所有匹配给定的正则表达式的子字符串
-
String replaceFirst(String regex, String replacement)
使用给定的replacement替换此字符串匹配给定的正则表达式的第一个子字符串
匹配(了解)--------------------------------------------
-
boolean matches(String regex)
告知此字符串是否匹配给定的正则表达式
切片(了解)--------------------------------------------
-
String[] split(String regex)
根据给定正则表达式的匹配拆分此字符串
-
String[] split(String regex, int limit)
根据匹配给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中
复习:
1、String转换基本数据类型、包装类
涉及到String类与其他结构之间的转换
String与基本数据类型和包装类之间的转换
-
String---->基本数据类型、包装类:
调用包装类的静态方法:parseXxx(str)
String str1="123";
int num=Integer.parseInt(str1); -
基本数据类型、包装类---->String
调用String重载的valueOf(xxx)
String str2 = String.valueOf(num);//"123"
//或
String str2=num+"";
2、String与字符数组转换
String与char[]之间的转换
-
String---->char[]:调用String的toCharArray()方法
str.toCharArray()
char[] charArray =
str2.toCharArray();
for (int i = 0; i <
charArray.length; i++) { System.out.println(charArray[i]);//输出charArray数组元素
}
-
char[]---->String:调用String的构造器
new String(arr);char[] arr=new char[]{'h','e','l','l','o'};
String str3 = new String(arr);
//new String(arr);
System.out.println(arr);//hello
3、String与byte[]之间的转换
-
String---->byte[],编码
调用String的getBytes()方法
String str1="abc123";
byte[] bytes = str1.getBytes();
System.out.println(Arrays.toString(bytes));
//[97, 98, 99, 49, 50, 51]
编码:字符串---->字节(看得懂-->看不懂)
解码:编码的逆过程 字节---->字符串
-
byte[]---->String,解码
调用String的构造器
String str2 = new String(bytes);
System.out.println(str2);//abc123中国
String str3 = new String(gbks);
System.out.println(str3);//abc123�й�出现乱码:解析时没有用gbk,编码集和解码集不一致
指定后没有乱码:
String gbk = new String(gbks, "gbk");
System.out.println(gbk);//abc123中国
说明:解码时,要求解码使用的字符集必须与编码时使用的字符集一致
StringBuffer类
关于 StringBuffer和 StringBuilder的使用
String、StringBuffer、StringBuilder三者异同:
String:不可变的字符序列;底层使用char[]存储
StringBuffer:可变的字符序列,线程安全的,效率低;底层使用char[]存储
StringBuilder:可变的字符序列,jdk5.0新增的,线程不安全的,效率高;底层使用char[]存储
源码分析:
String str=new String();//new char[0];
String str1=new String("abc"); //new char[]{'a','b','c'};
StringBuffer sb1=new StringBuffer(); //char[] value=new char[16];
相当于底层创建了一个长度为16的数组
sb1.oppend('a');//value[0]='a';
//相当于value首位置赋值为a,
sb1.oppend('b');//value[1]='b';
可变:可以在现有的加
StringBuffer str2=new StringBuffer("abc");//char[] value=new char["abc".length()+16]
每次造完后会额外空出16个
问题1:
StringBuffer str2=new StringBuffer();
System.out.println(sb1.length());//0
//
StringBuffer str2=new StringBuffer("abc");
System.out.println(sb1.length());//3
问题2:
扩容问题:如果要添加的数据底层数据盛不下了,那就需要扩容底层数组
默认情况下,扩容为原来的2倍+2,同时将原有数组的元素复制到新的数组中
指导意义:开发中使用:StringBuffer(int capacity)或StringBuilder(int capacity),指定容量,避免扩容复制
StringBuffer类的常用方法
-
StringBuffer append(xxx):
提供了很多的append()方法,用于进行字符串拼接
方法链:s.append().append().append()
StringBuffer s1=new StringBuffer("abc");
s1.append(1);
s1.append("1");
System.out.println(s1);//abc11 -
StringBuffer delete(int start,int end);
删除指定位置的内容
左闭右开
s1.delete(2,4);
System.out.println(s1);//ab1 -
StringBuffer replace(int start,int end,String str):
把[start,end)左闭右开位置替换为str
s1.replace(2,4,"hello");
System.out.println(s1);
//abhello1 -
StringBuffer insert(int offset,xxx):
在指定位置插入xxx
s1.insert(2,false);
System.out.println(s1);
//abfalsec11 -
StringBuffer reverse():
把当前字符序列逆转
s1.reverse();
System.out.println(s1);//11cba -
public int indexOf(String str)
-
public String substring(int start,int end)
返回一个从start开始到end结束的左闭右开的子字符串
原字符串s1没有变化
String s2 = s1.substring(2, 4);
System.out.println(s1.length());//5
System.out.println(s2);//cb -
public int length()
-
public char charAt(int n)
-
public void setChatAt(int n ,char ch)
总结:
增:append(xxx)
删:delete(int start,int end)
改:setChatAt(int n ,char ch)/replace(int start,int end,String str)
查:charAt(int n)
插:insert(int offset,xxx)
长度:length();
遍历:for()+charAt()/toString()
String、StringBuffer、StringBuilder三者效率:
StringBuilder>StringBuffer>String
String、StringBuffer、StringBuilder之间的转换:
-
String--->StringBuffer、StringBuilder:
调用StringBuffer、StringBuilder的构造器
new StringBuffer(String str);
-
StringBuffer、StringBuilder--->String:
①调用String的构造器
②StringBuffer、StringBuilder的toString()方法
JDK8之前的日期时间API测试
-
System类中的currentTimeMillis()
用来返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差
称为时间戳
此方法适于计算时间差
long time = System.currentTimeMillis();
System.out.println(time);//1633966657021
-
Date类
-
两个构造器的使用:java.util.Date类
-
构造器一:Date();
创建一个对应当前时间的Date对象
Date date1 = new Date();
System.out.println(date1.toString());
//Mon Oct 11 23:50:11 CST 2021
-
构造器二:创建指定毫秒数的Date对象
1633967701698L
Date date2 = new Date(1633967701698l);
System.out.println(date2.toString());
//Mon Oct 11 23:55:01 CST 2021
还有|------java.sql.Date类
-
两个方法的使用
-
toString():显示当前的年月日时分秒
-
getTime():获取当前Date对象的毫秒数(时间戳)
System.out.println(date1.getTime());//1633967701698
-
java.sql.Date对应着数据库中的日期类型的变量
如何实例化:创建java.sql.Date对象
java.sql.Date date3 = new java.sql.Date(345678368494L);
System.out.println(date3);
//1980-12-15只打印年月日
-
sql.Date----->util.Date对象:多态
-
util.Date----->sql.Date对象p470
情况一:强转√
Date date4=new java.sql.Date(5678976534567L);
java.sql.Date date5=(java.sql.Date)date4;
情况二:
Date date6=new Date();
java.sql.Date date7=new java.sql.Date(date6.getTime());
//用getTime()方法找到time,把毫秒数扔到构造器里作为参数
习题
JDK8中新日期时间API
Java比较器
System类
Math类
String类
例子:
-
代表字符串,使用一对“”引起来表示
-
是一个final类,不可被继承,代表不可变的字符序列
-
String实现了Serializable接口:表示字符串是支持序列化的(IO)
实现了Comparable接口:表示String可以比较大小
-
String内部定义了final char[] value用于储存字符串数据
-
通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串声明再字符串常量池中
String s1="abc";//字面量的定义方式String s2="abc"; -
字符串常量池中是不会存储相同内容的字符串:
使用String类的equals()比较,返回true的字符串
-
String代表了一个不可变的字符串序列,简称:不可变性,体现:
-
当对字符串重新赋值时,需要重写指定的内存区域赋值,不能使用原有的value进行赋值
String s1="abc";
String s2="abc";
s1="hello"; -
当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值
String s3="abc";
s3+="def";
System.out.println(s3);//abccdef -
当调用String的replace( )方法修改指定字符或字符串时,也需要重新指定内存区域赋值
String s4="abc";
String s5=s4.replace("a","m");
System.out.println(s4);//abc
System.out.println(s5);//mbc
-
String对象的创建
-
String的实例化方式:
-
通过字面量定义的方式
-
通过new+构造器的方式
//通过字面量定义的方式:
// 此时的s1和s2数据JavaEE声明在方法区中的字符串常量池中
String s1="javaEE";
String s2="javaEE";
//通过new+构造器的方式:
// 此时的s1和s2保存的地址值,是数据在堆空间中开辟空间以后对应的地址值
String s3=new String("javaEE");
String s4=new String("javaEE");
System.out.println(s1 == s2);//true
System.out.println(s1 == s3);//false
System.out.println(s1 == s4);//false
System.out.println(s3 == s4);//false
Person p1=new Person("Tom",12);
Person p2=new Person("Tom",12);
System.out.println(p1.name.equals(p2.name));//true
System.out.println(p1.name==p2.name);//true
-
面试题:
String s = new String("abc");方式创建对象,在内存中创建了几个对象?
两个:一个是在堆空间中new结构,另一个是char[ ]对应的常量池中的数据:“abc”
String s1="JavaEE";
String s2="hadoop";//基本
String s3="JavaEEhadoop";
String s4="JavaEE"+"hadoop";
String s5=s1+"hadoop";
String s6="JavaEE"+s2;
String s7=s1+s2;
System.out.println(s3 ==s4);//true
System.out.println(s3 =s5);//false
System.out.println(s3 =s6);//false
System.out.println(s3 =s7);//false
System.out.println(s5 =s6);//false
System.out.println(s5 =s7);//false
System.out.println(s6 =s7);//false
-
结论:
-
常量与常量的拼接结果在常量池,且常量池中不会存在相同内容的常量
-
只要其中有一个变量,结果就在堆中
-
如果拼接的结果调用intern()方法,返回值就在常量池中
String s8=s5.intern();//返回值得到的s8是常量池中已经存在的“JavaEEhadoop”
System.out.println(s3==s8);//true
补充:final
-
面试题:Java值传递
jdk1.6:字符串常量池存储在方法区(永久区)
jdk1.7:字符串常量池存储在堆空间
jdk1.8:字符串常量池存储在方法区(元空间)
String常用方法1
-
int length()
返回字符串的长度:return value.length
-
char charAt(int index)
返回某索引处的字符:return value[index]
String s1="helloworld";
System.out.println(s1.length());//10
System.out.println(s1.charAt(0));//h
System.out.println(s1.charAt(9));//d
System.out.println(s1.charAt(10));//越界注意下标长度不要越界
-
boolean isEmpty()
判断是否为空字符串:return value.length==0
(结果为true/false)
String s2="";
System.out.println(s2.isEmpty());//true -
String toLowerCase()
使用默认语言环境,将String中所有字符转换为小写
String s1="HelloWorld";
String s2=s1.toLowerCase(Locale.ROOT);//返回值接收为s2
System.out.println(s1);//HelloWorld,s1不可变,仍为原来字符串
System.out.println(s2);
//helloworld,改成小写以后字符串 -
String toUpperCase()
使用默认语言环境,将String中所有字符转换为大写
-
String trim()
返回字符串的副本,忽略前导空白和尾部空白(中间空格不变)
String s3=" he llo world ";
System.out.println("--"+s3+"--");
//-- he llo world --
System.out.println("--"+s3.trim()+"--");
//--he llo world-- -
boolean equals(Object obj)
比较字符串内容是否相同
-
boolean equalsIgnoreCase(String anotherString)
与equals方法类似,忽略大小写
String s1="HelloWorld";
String s2="helloworld";
System.out.println(s1.equals(s2));//false
System.out.println(s1.equalsIgnoreCase(s2));//true -
String concat(String str)
将指定的字符串连接到此字符串的结尾,等价于用“+”
String s3="abc";
String s4 = s3.concat("def");
System.out.println(s4);//abcdef -
int compareTo(String anotherString)
比较两个字符串的大小
String s5="abc";
String s6=new String("abe");
System.out.println(s5.compareTo(s6));//-2
//a是97,e是101
//涉及到字符串排序 -
String substring(int beginIndex)
返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个字符串
取出一个子字符串
String s7="北京尚硅谷教育";
String s8 = s7.substring(2);
System.out.println(s7);
//北京尚硅谷教育
System.out.println(s8);
//尚硅谷教育 -
String substring(int beginIndex,int endIndex)
返回一个新的字符串,它是此字符串的从beginIndex开始截取到endIndex(不包含)的一个字符串
[左闭右开)
String s7="北京尚硅谷教育";
String s9 = s7.substring(2, 5);//尚硅谷
String常用方法2
-
boolean endsWith(String suffix)
测试此字符串是否以指定的后缀结束
String str1="helloworld";
boolean b1=str1.endsWith("ld");
System.out.println(b1);//true -
boolean startsWith(String prefix)
测试此字符串是否以指定的前缀开始
String str1="helloworld";
boolean b2= str1.startsWith("He");
System.out.println(b2);//false -
boolean startsWith(String prefix,int toffset)
测试此字符串从指定索引开始的字符串是否以指定的前缀开始
从第2个开始,以"ll"开始(√)
String str1="helloworld";
boolean b3 = str1.startsWith("ll",2);
System.out.println(b3);//true
-
boolean contains(CharSequence s )
当且仅当此字符串包含指定的char值序列时,返回true
String str1="helloworld";
String str2="wo";
System.out.println(str1.contains(str2));//true -
int indexOf(String str)
返回指定子字符串在此字符串中第一次出现处的索引
String str1="helloworld";
System.out.println(str1.indexOf("lo"));//3
System.out.println(str1.indexOf("lol"));//-1:未找到的规定返回-1 -
int indexOf(String str, int fromIndex)
返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
从5开始找
String str1="helloworld";
System.out.println(str1.indexOf("lo",5));//-1 -
int lastIndexOf(String str)
返回指定子字符串在此字符串中最右边出现处的索引
0 1 2 3 4 5 6 7 8 9 10依旧从前往后数
h e l l o r w o r l d
String str3="hellorworld";
System.out.println(str3.lastIndexOf("or"));//7 -
int lastIndexOf(String str, int fromIndex)
返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索
0 1 2 3 4 5 6|7 8 9 10
h e l l o r w o r l d
String str3="hellorworld";
System.out.println(str3.lastIndexOf("or",6));//4
-
什么情况下,indexOf(str)和lastIndexOf(str)返回值相同?
情况一:存在唯一的一个str
情况二:不存在str
String常用方法3
替换-------------------------------------------------
-
String replace(char oldChar,char newChar)
返回一个新的字符串,他是通过newChar替换此字符串中出现的所有oldChar得到的
全改
String str1="北京尚硅谷教育北京";
String str2 =str1.replace('北', '东');
System.out.println(str1);//北京尚硅谷教育北京
System.out.println(str2);//东京尚硅谷教育东京 -
String replace(CharSequence target, CharSequence replacement)
使用指定的字面值替换序列替换此字符串所用匹配字面值目标序列的字符串
String str1="北京尚硅谷教育北京";
String str3 = str1.replace("北京", "上海");
//上海尚硅谷教育上海
-
String replaceAll(String regex:正则, String replacement)
使用给定的replacement替换此字符串所有匹配给定的正则表达式的子字符串
-
String replaceFirst(String regex, String replacement)
使用给定的replacement替换此字符串匹配给定的正则表达式的第一个子字符串
匹配(了解)--------------------------------------------
-
boolean matches(String regex)
告知此字符串是否匹配给定的正则表达式
切片(了解)--------------------------------------------
-
String[] split(String regex)
根据给定正则表达式的匹配拆分此字符串
-
String[] split(String regex, int limit)
根据匹配给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中
复习:
1、String转换基本数据类型、包装类
涉及到String类与其他结构之间的转换
String与基本数据类型和包装类之间的转换
-
String---->基本数据类型、包装类:
调用包装类的静态方法:parseXxx(str)
String str1="123";
int num=Integer.parseInt(str1); -
基本数据类型、包装类---->String
调用String重载的valueOf(xxx)
String str2 = String.valueOf(num);//"123"
//或
String str2=num+"";
2、String与字符数组转换
String与char[]之间的转换
-
String---->char[]:调用String的toCharArray()方法
str.toCharArray()
char[] charArray =
str2.toCharArray();
for (int i = 0; i <
charArray.length; i++) { System.out.println(charArray[i]);//输出charArray数组元素
}
-
char[]---->String:调用String的构造器
new String(arr);char[] arr=new char[]{'h','e','l','l','o'};
String str3 = new String(arr);
//new String(arr);
System.out.println(arr);//hello
3、String与byte[]之间的转换
-
String---->byte[],编码
调用String的getBytes()方法
String str1="abc123";
byte[] bytes = str1.getBytes();
System.out.println(Arrays.toString(bytes));
//[97, 98, 99, 49, 50, 51]
编码:字符串---->字节(看得懂-->看不懂)
解码:编码的逆过程 字节---->字符串
-
byte[]---->String,解码
调用String的构造器
String str2 = new String(bytes);
System.out.println(str2);//abc123中国
String str3 = new String(gbks);
System.out.println(str3);//abc123�й�出现乱码:解析时没有用gbk,编码集和解码集不一致
指定后没有乱码:
String gbk = new String(gbks, "gbk");
System.out.println(gbk);//abc123中国
说明:解码时,要求解码使用的字符集必须与编码时使用的字符集一致
StringBuffer类
关于 StringBuffer和 StringBuilder的使用
String、StringBuffer、StringBuilder三者异同:
String:不可变的字符序列;底层使用char[]存储
StringBuffer:可变的字符序列,线程安全的,效率低;底层使用char[]存储
StringBuilder:可变的字符序列,jdk5.0新增的,线程不安全的,效率高;底层使用char[]存储
源码分析:
String str=new String();//new char[0];
String str1=new String("abc"); //new char[]{'a','b','c'};
StringBuffer sb1=new StringBuffer(); //char[] value=new char[16];
相当于底层创建了一个长度为16的数组
sb1.oppend('a');//value[0]='a';
//相当于value首位置赋值为a,
sb1.oppend('b');//value[1]='b';
可变:可以在现有的加
StringBuffer str2=new StringBuffer("abc");//char[] value=new char["abc".length()+16]
每次造完后会额外空出16个
问题1:
StringBuffer str2=new StringBuffer();
System.out.println(sb1.length());//0
//
StringBuffer str2=new StringBuffer("abc");
System.out.println(sb1.length());//3
问题2:
扩容问题:如果要添加的数据底层数据盛不下了,那就需要扩容底层数组
默认情况下,扩容为原来的2倍+2,同时将原有数组的元素复制到新的数组中
指导意义:开发中使用:StringBuffer(int capacity)或StringBuilder(int capacity),指定容量,避免扩容复制
StringBuffer类的常用方法
-
StringBuffer append(xxx):
提供了很多的append()方法,用于进行字符串拼接
方法链:s.append().append().append()
StringBuffer s1=new StringBuffer("abc");
s1.append(1);
s1.append("1");
System.out.println(s1);//abc11 -
StringBuffer delete(int start,int end);
删除指定位置的内容
左闭右开
s1.delete(2,4);
System.out.println(s1);//ab1 -
StringBuffer replace(int start,int end,String str):
把[start,end)左闭右开位置替换为str
s1.replace(2,4,"hello");
System.out.println(s1);
//abhello1 -
StringBuffer insert(int offset,xxx):
在指定位置插入xxx
s1.insert(2,false);
System.out.println(s1);
//abfalsec11 -
StringBuffer reverse():
把当前字符序列逆转
s1.reverse();
System.out.println(s1);//11cba -
public int indexOf(String str)
-
public String substring(int start,int end)
返回一个从start开始到end结束的左闭右开的子字符串
原字符串s1没有变化
String s2 = s1.substring(2, 4);
System.out.println(s1.length());//5
System.out.println(s2);//cb -
public int length()
-
public char charAt(int n)
-
public void setChatAt(int n ,char ch)
总结:
增:append(xxx)
删:delete(int start,int end)
改:setChatAt(int n ,char ch)/replace(int start,int end,String str)
查:charAt(int n)
插:insert(int offset,xxx)
长度:length();
遍历:for()+charAt()/toString()
String、StringBuffer、StringBuilder三者效率:
StringBuilder>StringBuffer>String
String、StringBuffer、StringBuilder之间的转换:
-
String--->StringBuffer、StringBuilder:
调用StringBuffer、StringBuilder的构造器
new StringBuffer(String str);
-
StringBuffer、StringBuilder--->String:
①调用String的构造器
②StringBuffer、StringBuilder的toString()方法
JDK8之前的日期时间API测试
-
System类中的currentTimeMillis()
用来返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差
称为时间戳
此方法适于计算时间差
long time = System.currentTimeMillis();
System.out.println(time);//1633966657021
-
Date类
-
两个构造器的使用:java.util.Date类
-
构造器一:Date();
创建一个对应当前时间的Date对象
Date date1 = new Date();
System.out.println(date1.toString());
//Mon Oct 11 23:50:11 CST 2021
-
构造器二:创建指定毫秒数的Date对象
1633967701698L
Date date2 = new Date(1633967701698l);
System.out.println(date2.toString());
//Mon Oct 11 23:55:01 CST 2021
还有|------java.sql.Date类
-
两个方法的使用
-
toString():显示当前的年月日时分秒
-
getTime():获取当前Date对象的毫秒数(时间戳)
System.out.println(date1.getTime());//1633967701698
-
java.sql.Date对应着数据库中的日期类型的变量
如何实例化:创建java.sql.Date对象
java.sql.Date date3 = new java.sql.Date(345678368494L);
System.out.println(date3);
//1980-12-15只打印年月日
-
sql.Date----->util.Date对象:多态
-
util.Date----->sql.Date对象p470
情况一:强转√
Date date4=new java.sql.Date(5678976534567L);
java.sql.Date date5=(java.sql.Date)date4;
情况二:
Date date6=new Date();
java.sql.Date date7=new java.sql.Date(date6.getTime());
//用getTime()方法找到time,把毫秒数扔到构造器里作为参数
习题
JDK8中新日期时间API
Java比较器
System类
Math类
String类
例子:
-
代表字符串,使用一对“”引起来表示
-
是一个final类,不可被继承,代表不可变的字符序列
-
String实现了Serializable接口:表示字符串是支持序列化的(IO)
实现了Comparable接口:表示String可以比较大小
-
String内部定义了final char[] value用于储存字符串数据
-
通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串声明再字符串常量池中
String s1="abc";//字面量的定义方式String s2="abc"; -
字符串常量池中是不会存储相同内容的字符串:
使用String类的equals()比较,返回true的字符串
-
String代表了一个不可变的字符串序列,简称:不可变性,体现:
-
当对字符串重新赋值时,需要重写指定的内存区域赋值,不能使用原有的value进行赋值
String s1="abc";
String s2="abc";
s1="hello"; -
当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值
String s3="abc";
s3+="def";
System.out.println(s3);//abccdef -
当调用String的replace( )方法修改指定字符或字符串时,也需要重新指定内存区域赋值
String s4="abc";
String s5=s4.replace("a","m");
System.out.println(s4);//abc
System.out.println(s5);//mbc
-
String对象的创建
-
String的实例化方式:
-
通过字面量定义的方式
-
通过new+构造器的方式
//通过字面量定义的方式:
// 此时的s1和s2数据JavaEE声明在方法区中的字符串常量池中
String s1="javaEE";
String s2="javaEE";
//通过new+构造器的方式:
// 此时的s1和s2保存的地址值,是数据在堆空间中开辟空间以后对应的地址值
String s3=new String("javaEE");
String s4=new String("javaEE");
System.out.println(s1 == s2);//true
System.out.println(s1 == s3);//false
System.out.println(s1 == s4);//false
System.out.println(s3 == s4);//false
Person p1=new Person("Tom",12);
Person p2=new Person("Tom",12);
System.out.println(p1.name.equals(p2.name));//true
System.out.println(p1.name==p2.name);//true
-
面试题:
String s = new String("abc");方式创建对象,在内存中创建了几个对象?
两个:一个是在堆空间中new结构,另一个是char[ ]对应的常量池中的数据:“abc”
String s1="JavaEE";
String s2="hadoop";//基本
String s3="JavaEEhadoop";
String s4="JavaEE"+"hadoop";
String s5=s1+"hadoop";
String s6="JavaEE"+s2;
String s7=s1+s2;
System.out.println(s3 ==s4);//true
System.out.println(s3 =s5);//false
System.out.println(s3 =s6);//false
System.out.println(s3 =s7);//false
System.out.println(s5 =s6);//false
System.out.println(s5 =s7);//false
System.out.println(s6 =s7);//false
-
结论:
-
常量与常量的拼接结果在常量池,且常量池中不会存在相同内容的常量
-
只要其中有一个变量,结果就在堆中
-
如果拼接的结果调用intern()方法,返回值就在常量池中
String s8=s5.intern();//返回值得到的s8是常量池中已经存在的“JavaEEhadoop”
System.out.println(s3==s8);//true
补充:final
-
面试题:Java值传递
jdk1.6:字符串常量池存储在方法区(永久区)
jdk1.7:字符串常量池存储在堆空间
jdk1.8:字符串常量池存储在方法区(元空间)
String常用方法1
-
int length()
返回字符串的长度:return value.length
-
char charAt(int index)
返回某索引处的字符:return value[index]
String s1="helloworld";
System.out.println(s1.length());//10
System.out.println(s1.charAt(0));//h
System.out.println(s1.charAt(9));//d
System.out.println(s1.charAt(10));//越界注意下标长度不要越界
-
boolean isEmpty()
判断是否为空字符串:return value.length==0
(结果为true/false)
String s2="";
System.out.println(s2.isEmpty());//true -
String toLowerCase()
使用默认语言环境,将String中所有字符转换为小写
String s1="HelloWorld";
String s2=s1.toLowerCase(Locale.ROOT);//返回值接收为s2
System.out.println(s1);//HelloWorld,s1不可变,仍为原来字符串
System.out.println(s2);
//helloworld,改成小写以后字符串 -
String toUpperCase()
使用默认语言环境,将String中所有字符转换为大写
-
String trim()
返回字符串的副本,忽略前导空白和尾部空白(中间空格不变)
String s3=" he llo world ";
System.out.println("--"+s3+"--");
//-- he llo world --
System.out.println("--"+s3.trim()+"--");
//--he llo world-- -
boolean equals(Object obj)
比较字符串内容是否相同
-
boolean equalsIgnoreCase(String anotherString)
与equals方法类似,忽略大小写
String s1="HelloWorld";
String s2="helloworld";
System.out.println(s1.equals(s2));//false
System.out.println(s1.equalsIgnoreCase(s2));//true -
String concat(String str)
将指定的字符串连接到此字符串的结尾,等价于用“+”
String s3="abc";
String s4 = s3.concat("def");
System.out.println(s4);//abcdef -
int compareTo(String anotherString)
比较两个字符串的大小
String s5="abc";
String s6=new String("abe");
System.out.println(s5.compareTo(s6));//-2
//a是97,e是101
//涉及到字符串排序 -
String substring(int beginIndex)
返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个字符串
取出一个子字符串
String s7="北京尚硅谷教育";
String s8 = s7.substring(2);
System.out.println(s7);
//北京尚硅谷教育
System.out.println(s8);
//尚硅谷教育 -
String substring(int beginIndex,int endIndex)
返回一个新的字符串,它是此字符串的从beginIndex开始截取到endIndex(不包含)的一个字符串
[左闭右开)
String s7="北京尚硅谷教育";
String s9 = s7.substring(2, 5);//尚硅谷
String常用方法2
-
boolean endsWith(String suffix)
测试此字符串是否以指定的后缀结束
String str1="helloworld";
boolean b1=str1.endsWith("ld");
System.out.println(b1);//true -
boolean startsWith(String prefix)
测试此字符串是否以指定的前缀开始
String str1="helloworld";
boolean b2= str1.startsWith("He");
System.out.println(b2);//false -
boolean startsWith(String prefix,int toffset)
测试此字符串从指定索引开始的字符串是否以指定的前缀开始
从第2个开始,以"ll"开始(√)
String str1="helloworld";
boolean b3 = str1.startsWith("ll",2);
System.out.println(b3);//true
-
boolean contains(CharSequence s )
当且仅当此字符串包含指定的char值序列时,返回true
String str1="helloworld";
String str2="wo";
System.out.println(str1.contains(str2));//true -
int indexOf(String str)
返回指定子字符串在此字符串中第一次出现处的索引
String str1="helloworld";
System.out.println(str1.indexOf("lo"));//3
System.out.println(str1.indexOf("lol"));//-1:未找到的规定返回-1 -
int indexOf(String str, int fromIndex)
返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
从5开始找
String str1="helloworld";
System.out.println(str1.indexOf("lo",5));//-1 -
int lastIndexOf(String str)
返回指定子字符串在此字符串中最右边出现处的索引
0 1 2 3 4 5 6 7 8 9 10依旧从前往后数
h e l l o r w o r l d
String str3="hellorworld";
System.out.println(str3.lastIndexOf("or"));//7 -
int lastIndexOf(String str, int fromIndex)
返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索
0 1 2 3 4 5 6|7 8 9 10
h e l l o r w o r l d
String str3="hellorworld";
System.out.println(str3.lastIndexOf("or",6));//4
-
什么情况下,indexOf(str)和lastIndexOf(str)返回值相同?
情况一:存在唯一的一个str
情况二:不存在str
String常用方法3
替换-------------------------------------------------
-
String replace(char oldChar,char newChar)
返回一个新的字符串,他是通过newChar替换此字符串中出现的所有oldChar得到的
全改
String str1="北京尚硅谷教育北京";
String str2 =str1.replace('北', '东');
System.out.println(str1);//北京尚硅谷教育北京
System.out.println(str2);//东京尚硅谷教育东京 -
String replace(CharSequence target, CharSequence replacement)
使用指定的字面值替换序列替换此字符串所用匹配字面值目标序列的字符串
String str1="北京尚硅谷教育北京";
String str3 = str1.replace("北京", "上海");
//上海尚硅谷教育上海
-
String replaceAll(String regex:正则, String replacement)
使用给定的replacement替换此字符串所有匹配给定的正则表达式的子字符串
-
String replaceFirst(String regex, String replacement)
使用给定的replacement替换此字符串匹配给定的正则表达式的第一个子字符串
匹配(了解)--------------------------------------------
-
boolean matches(String regex)
告知此字符串是否匹配给定的正则表达式
切片(了解)--------------------------------------------
-
String[] split(String regex)
根据给定正则表达式的匹配拆分此字符串
-
String[] split(String regex, int limit)
根据匹配给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中
复习:
1、String转换基本数据类型、包装类
涉及到String类与其他结构之间的转换
String与基本数据类型和包装类之间的转换
-
String---->基本数据类型、包装类:
调用包装类的静态方法:parseXxx(str)
String str1="123";
int num=Integer.parseInt(str1); -
基本数据类型、包装类---->String
调用String重载的valueOf(xxx)
String str2 = String.valueOf(num);//"123"
//或
String str2=num+"";
2、String与字符数组转换
String与char[]之间的转换
-
String---->char[]:调用String的toCharArray()方法
str.toCharArray()
char[] charArray =
str2.toCharArray();
for (int i = 0; i <
charArray.length; i++) { System.out.println(charArray[i]);//输出charArray数组元素
}
-
char[]---->String:调用String的构造器
new String(arr);char[] arr=new char[]{'h','e','l','l','o'};
String str3 = new String(arr);
//new String(arr);
System.out.println(arr);//hello
3、String与byte[]之间的转换
-
String---->byte[],编码
调用String的getBytes()方法
String str1="abc123";
byte[] bytes = str1.getBytes();
System.out.println(Arrays.toString(bytes));
//[97, 98, 99, 49, 50, 51]
编码:字符串---->字节(看得懂-->看不懂)
解码:编码的逆过程 字节---->字符串
-
byte[]---->String,解码
调用String的构造器
String str2 = new String(bytes);
System.out.println(str2);//abc123中国
String str3 = new String(gbks);
System.out.println(str3);//abc123�й�出现乱码:解析时没有用gbk,编码集和解码集不一致
指定后没有乱码:
String gbk = new String(gbks, "gbk");
System.out.println(gbk);//abc123中国
说明:解码时,要求解码使用的字符集必须与编码时使用的字符集一致
StringBuffer类
关于 StringBuffer和 StringBuilder的使用
String、StringBuffer、StringBuilder三者异同:
String:不可变的字符序列;底层使用char[]存储
StringBuffer:可变的字符序列,线程安全的,效率低;底层使用char[]存储
StringBuilder:可变的字符序列,jdk5.0新增的,线程不安全的,效率高;底层使用char[]存储
源码分析:
String str=new String();//new char[0];
String str1=new String("abc"); //new char[]{'a','b','c'};
StringBuffer sb1=new StringBuffer(); //char[] value=new char[16];
相当于底层创建了一个长度为16的数组
sb1.oppend('a');//value[0]='a';
//相当于value首位置赋值为a,
sb1.oppend('b');//value[1]='b';
可变:可以在现有的加
StringBuffer str2=new StringBuffer("abc");//char[] value=new char["abc".length()+16]
每次造完后会额外空出16个
问题1:
StringBuffer str2=new StringBuffer();
System.out.println(sb1.length());//0
//
StringBuffer str2=new StringBuffer("abc");
System.out.println(sb1.length());//3
问题2:
扩容问题:如果要添加的数据底层数据盛不下了,那就需要扩容底层数组
默认情况下,扩容为原来的2倍+2,同时将原有数组的元素复制到新的数组中
指导意义:开发中使用:StringBuffer(int capacity)或StringBuilder(int capacity),指定容量,避免扩容复制
StringBuffer类的常用方法
-
StringBuffer append(xxx):
提供了很多的append()方法,用于进行字符串拼接
方法链:s.append().append().append()
StringBuffer s1=new StringBuffer("abc");
s1.append(1);
s1.append("1");
System.out.println(s1);//abc11 -
StringBuffer delete(int start,int end);
删除指定位置的内容
左闭右开
s1.delete(2,4);
System.out.println(s1);//ab1 -
StringBuffer replace(int start,int end,String str):
把[start,end)左闭右开位置替换为str
s1.replace(2,4,"hello");
System.out.println(s1);
//abhello1 -
StringBuffer insert(int offset,xxx):
在指定位置插入xxx
s1.insert(2,false);
System.out.println(s1);
//abfalsec11 -
StringBuffer reverse():
把当前字符序列逆转
s1.reverse();
System.out.println(s1);//11cba -
public int indexOf(String str)
-
public String substring(int start,int end)
返回一个从start开始到end结束的左闭右开的子字符串
原字符串s1没有变化
String s2 = s1.substring(2, 4);
System.out.println(s1.length());//5
System.out.println(s2);//cb -
public int length()
-
public char charAt(int n)
-
public void setChatAt(int n ,char ch)
总结:
增:append(xxx)
删:delete(int start,int end)
改:setChatAt(int n ,char ch)/replace(int start,int end,String str)
查:charAt(int n)
插:insert(int offset,xxx)
长度:length();
遍历:for()+charAt()/toString()
String、StringBuffer、StringBuilder三者效率:
StringBuilder>StringBuffer>String
String、StringBuffer、StringBuilder之间的转换:
-
String--->StringBuffer、StringBuilder:
调用StringBuffer、StringBuilder的构造器
new StringBuffer(String str);
-
StringBuffer、StringBuilder--->String:
①调用String的构造器
②StringBuffer、StringBuilder的toString()方法
JDK8之前的日期时间API测试
-
System类中的currentTimeMillis()
用来返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差
称为时间戳
此方法适于计算时间差
long time = System.currentTimeMillis();
System.out.println(time);//1633966657021
-
Date类
-
两个构造器的使用:java.util.Date类
-
构造器一:Date();
创建一个对应当前时间的Date对象
Date date1 = new Date();
System.out.println(date1.toString());
//Mon Oct 11 23:50:11 CST 2021
-
构造器二:创建指定毫秒数的Date对象
1633967701698L
Date date2 = new Date(1633967701698l);
System.out.println(date2.toString());
//Mon Oct 11 23:55:01 CST 2021
还有|------java.sql.Date类
-
两个方法的使用
-
toString():显示当前的年月日时分秒
-
getTime():获取当前Date对象的毫秒数(时间戳)
System.out.println(date1.getTime());//1633967701698
-
java.sql.Date对应着数据库中的日期类型的变量
如何实例化:创建java.sql.Date对象
java.sql.Date date3 = new java.sql.Date(345678368494L);
System.out.println(date3);
//1980-12-15只打印年月日
-
sql.Date----->util.Date对象:多态
-
util.Date----->sql.Date对象p470
情况一:强转√
Date date4=new java.sql.Date(5678976534567L);
java.sql.Date date5=(java.sql.Date)date4;
情况二:
Date date6=new Date();
java.sql.Date date7=new java.sql.Date(date6.getTime());
//用getTime()方法找到time,把毫秒数扔到构造器里作为参数
习题
String类
例子:
-
代表字符串,使用一对“”引起来表示
-
是一个final类,不可被继承,代表不可变的字符序列
-
String实现了Serializable接口:表示字符串是支持序列化的(IO)
实现了Comparable接口:表示String可以比较大小
-
String内部定义了final char[] value用于储存字符串数据
-
通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串声明再字符串常量池中
String s1="abc";//字面量的定义方式String s2="abc"; -
字符串常量池中是不会存储相同内容的字符串:
使用String类的equals()比较,返回true的字符串
-
String代表了一个不可变的字符串序列,简称:不可变性,体现:
-
当对字符串重新赋值时,需要重写指定的内存区域赋值,不能使用原有的value进行赋值
String s1="abc";
String s2="abc";
s1="hello"; -
当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值
String s3="abc";
s3+="def";
System.out.println(s3);//abccdef -
当调用String的replace( )方法修改指定字符或字符串时,也需要重新指定内存区域赋值
String s4="abc";
String s5=s4.replace("a","m");
System.out.println(s4);//abc
System.out.println(s5);//mbc
-
String对象的创建
-
String的实例化方式:
-
通过字面量定义的方式
-
通过new+构造器的方式
//通过字面量定义的方式:
// 此时的s1和s2数据JavaEE声明在方法区中的字符串常量池中
String s1="javaEE";
String s2="javaEE";
//通过new+构造器的方式:
// 此时的s1和s2保存的地址值,是数据在堆空间中开辟空间以后对应的地址值
String s3=new String("javaEE");
String s4=new String("javaEE");
System.out.println(s1 == s2);//true
System.out.println(s1 == s3);//false
System.out.println(s1 == s4);//false
System.out.println(s3 == s4);//false
Person p1=new Person("Tom",12);
Person p2=new Person("Tom",12);
System.out.println(p1.name.equals(p2.name));//true
System.out.println(p1.name==p2.name);//true
-
面试题:
String s = new String("abc");方式创建对象,在内存中创建了几个对象?
两个:一个是在堆空间中new结构,另一个是char[ ]对应的常量池中的数据:“abc”
String s1="JavaEE";
String s2="hadoop";//基本
String s3="JavaEEhadoop";
String s4="JavaEE"+"hadoop";
String s5=s1+"hadoop";
String s6="JavaEE"+s2;
String s7=s1+s2;
System.out.println(s3 ==s4);//true
System.out.println(s3 =s5);//false
System.out.println(s3 =s6);//false
System.out.println(s3 =s7);//false
System.out.println(s5 =s6);//false
System.out.println(s5 =s7);//false
System.out.println(s6 =s7);//false
-
结论:
-
常量与常量的拼接结果在常量池,且常量池中不会存在相同内容的常量
-
只要其中有一个变量,结果就在堆中
-
如果拼接的结果调用intern()方法,返回值就在常量池中
String s8=s5.intern();//返回值得到的s8是常量池中已经存在的“JavaEEhadoop”
System.out.println(s3==s8);//true
补充:final
-
面试题:Java值传递
jdk1.6:字符串常量池存储在方法区(永久区)
jdk1.7:字符串常量池存储在堆空间
jdk1.8:字符串常量池存储在方法区(元空间)
String常用方法1
-
int length()
返回字符串的长度:return value.length
-
char charAt(int index)
返回某索引处的字符:return value[index]
String s1="helloworld";
System.out.println(s1.length());//10
System.out.println(s1.charAt(0));//h
System.out.println(s1.charAt(9));//d
System.out.println(s1.charAt(10));//越界注意下标长度不要越界
-
boolean isEmpty()
判断是否为空字符串:return value.length==0
(结果为true/false)
String s2="";
System.out.println(s2.isEmpty());//true -
String toLowerCase()
使用默认语言环境,将String中所有字符转换为小写
String s1="HelloWorld";
String s2=s1.toLowerCase(Locale.ROOT);//返回值接收为s2
System.out.println(s1);//HelloWorld,s1不可变,仍为原来字符串
System.out.println(s2);
//helloworld,改成小写以后字符串 -
String toUpperCase()
使用默认语言环境,将String中所有字符转换为大写
-
String trim()
返回字符串的副本,忽略前导空白和尾部空白(中间空格不变)
String s3=" he llo world ";
System.out.println("--"+s3+"--");
//-- he llo world --
System.out.println("--"+s3.trim()+"--");
//--he llo world-- -
boolean equals(Object obj)
比较字符串内容是否相同
-
boolean equalsIgnoreCase(String anotherString)
与equals方法类似,忽略大小写
String s1="HelloWorld";
String s2="helloworld";
System.out.println(s1.equals(s2));//false
System.out.println(s1.equalsIgnoreCase(s2));//true -
String concat(String str)
将指定的字符串连接到此字符串的结尾,等价于用“+”
String s3="abc";
String s4 = s3.concat("def");
System.out.println(s4);//abcdef -
int compareTo(String anotherString)
比较两个字符串的大小
String s5="abc";
String s6=new String("abe");
System.out.println(s5.compareTo(s6));//-2
//a是97,e是101
//涉及到字符串排序 -
String substring(int beginIndex)
返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个字符串
取出一个子字符串
String s7="北京尚硅谷教育";
String s8 = s7.substring(2);
System.out.println(s7);
//北京尚硅谷教育
System.out.println(s8);
//尚硅谷教育 -
String substring(int beginIndex,int endIndex)
返回一个新的字符串,它是此字符串的从beginIndex开始截取到endIndex(不包含)的一个字符串
[左闭右开)
String s7="北京尚硅谷教育";
String s9 = s7.substring(2, 5);//尚硅谷
String常用方法2
-
boolean endsWith(String suffix)
测试此字符串是否以指定的后缀结束
String str1="helloworld";
boolean b1=str1.endsWith("ld");
System.out.println(b1);//true -
boolean startsWith(String prefix)
测试此字符串是否以指定的前缀开始
String str1="helloworld";
boolean b2= str1.startsWith("He");
System.out.println(b2);//false -
boolean startsWith(String prefix,int toffset)
测试此字符串从指定索引开始的字符串是否以指定的前缀开始
从第2个开始,以"ll"开始(√)
String str1="helloworld";
boolean b3 = str1.startsWith("ll",2);
System.out.println(b3);//true
-
boolean contains(CharSequence s )
当且仅当此字符串包含指定的char值序列时,返回true
String str1="helloworld";
String str2="wo";
System.out.println(str1.contains(str2));//true -
int indexOf(String str)
返回指定子字符串在此字符串中第一次出现处的索引
String str1="helloworld";
System.out.println(str1.indexOf("lo"));//3
System.out.println(str1.indexOf("lol"));//-1:未找到的规定返回-1 -
int indexOf(String str, int fromIndex)
返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
从5开始找
String str1="helloworld";
System.out.println(str1.indexOf("lo",5));//-1 -
int lastIndexOf(String str)
返回指定子字符串在此字符串中最右边出现处的索引
0 1 2 3 4 5 6 7 8 9 10依旧从前往后数
h e l l o r w o r l d
String str3="hellorworld";
System.out.println(str3.lastIndexOf("or"));//7 -
int lastIndexOf(String str, int fromIndex)
返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索
0 1 2 3 4 5 6|7 8 9 10
h e l l o r w o r l d
String str3="hellorworld";
System.out.println(str3.lastIndexOf("or",6));//4
-
什么情况下,indexOf(str)和lastIndexOf(str)返回值相同?
情况一:存在唯一的一个str
情况二:不存在str
String常用方法3
替换-------------------------------------------------
-
String replace(char oldChar,char newChar)
返回一个新的字符串,他是通过newChar替换此字符串中出现的所有oldChar得到的
全改
String str1="北京尚硅谷教育北京";
String str2 =str1.replace('北', '东');
System.out.println(str1);//北京尚硅谷教育北京
System.out.println(str2);//东京尚硅谷教育东京 -
String replace(CharSequence target, CharSequence replacement)
使用指定的字面值替换序列替换此字符串所用匹配字面值目标序列的字符串
String str1="北京尚硅谷教育北京";
String str3 = str1.replace("北京", "上海");
//上海尚硅谷教育上海
-
String replaceAll(String regex:正则, String replacement)
使用给定的replacement替换此字符串所有匹配给定的正则表达式的子字符串
-
String replaceFirst(String regex, String replacement)
使用给定的replacement替换此字符串匹配给定的正则表达式的第一个子字符串
匹配(了解)--------------------------------------------
-
boolean matches(String regex)
告知此字符串是否匹配给定的正则表达式
切片(了解)--------------------------------------------
-
String[] split(String regex)
根据给定正则表达式的匹配拆分此字符串
-
String[] split(String regex, int limit)
根据匹配给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中
复习:
1、String转换基本数据类型、包装类
涉及到String类与其他结构之间的转换
String与基本数据类型和包装类之间的转换
-
String---->基本数据类型、包装类:
调用包装类的静态方法:parseXxx(str)
String str1="123";
int num=Integer.parseInt(str1); -
基本数据类型、包装类---->String
调用String重载的valueOf(xxx)
String str2 = String.valueOf(num);//"123"
//或
String str2=num+"";
2、String与字符数组转换
String与char[]之间的转换
-
String---->char[]:调用String的toCharArray()方法
str.toCharArray()
char[] charArray =
str2.toCharArray();
for (int i = 0; i <
charArray.length; i++) { System.out.println(charArray[i]);//输出charArray数组元素
}
-
char[]---->String:调用String的构造器
new String(arr);char[] arr=new char[]{'h','e','l','l','o'};
String str3 = new String(arr);
//new String(arr);
System.out.println(arr);//hello
3、String与byte[]之间的转换
-
String---->byte[],编码
调用String的getBytes()方法
String str1="abc123";
byte[] bytes = str1.getBytes();
System.out.println(Arrays.toString(bytes));
//[97, 98, 99, 49, 50, 51]
编码:字符串---->字节(看得懂-->看不懂)
解码:编码的逆过程 字节---->字符串
-
byte[]---->String,解码
调用String的构造器
String str2 = new String(bytes);
System.out.println(str2);//abc123中国
String str3 = new String(gbks);
System.out.println(str3);//abc123�й�出现乱码:解析时没有用gbk,编码集和解码集不一致
指定后没有乱码:
String gbk = new String(gbks, "gbk");
System.out.println(gbk);//abc123中国
说明:解码时,要求解码使用的字符集必须与编码时使用的字符集一致
StringBuffer类
关于 StringBuffer和 StringBuilder的使用
String、StringBuffer、StringBuilder三者异同:
String:不可变的字符序列;底层使用char[]存储
StringBuffer:可变的字符序列,线程安全的,效率低;底层使用char[]存储
StringBuilder:可变的字符序列,jdk5.0新增的,线程不安全的,效率高;底层使用char[]存储
源码分析:
String str=new String();//new char[0];
String str1=new String("abc"); //new char[]{'a','b','c'};
StringBuffer sb1=new StringBuffer(); //char[] value=new char[16];
相当于底层创建了一个长度为16的数组
sb1.oppend('a');//value[0]='a';
//相当于value首位置赋值为a,
sb1.oppend('b');//value[1]='b';
可变:可以在现有的加
StringBuffer str2=new StringBuffer("abc");//char[] value=new char["abc".length()+16]
每次造完后会额外空出16个
问题1:
StringBuffer str2=new StringBuffer();
System.out.println(sb1.length());//0
//
StringBuffer str2=new StringBuffer("abc");
System.out.println(sb1.length());//3
问题2:
扩容问题:如果要添加的数据底层数据盛不下了,那就需要扩容底层数组
默认情况下,扩容为原来的2倍+2,同时将原有数组的元素复制到新的数组中
指导意义:开发中使用:StringBuffer(int capacity)或StringBuilder(int capacity),指定容量,避免扩容复制
StringBuffer类的常用方法
-
StringBuffer append(xxx):
提供了很多的append()方法,用于进行字符串拼接
方法链:s.append().append().append()
StringBuffer s1=new StringBuffer("abc");
s1.append(1);
s1.append("1");
System.out.println(s1);//abc11 -
StringBuffer delete(int start,int end);
删除指定位置的内容
左闭右开
s1.delete(2,4);
System.out.println(s1);//ab1 -
StringBuffer replace(int start,int end,String str):
把[start,end)左闭右开位置替换为str
s1.replace(2,4,"hello");
System.out.println(s1);
//abhello1 -
StringBuffer insert(int offset,xxx):
在指定位置插入xxx
s1.insert(2,false);
System.out.println(s1);
//abfalsec11 -
StringBuffer reverse():
把当前字符序列逆转
s1.reverse();
System.out.println(s1);//11cba -
public int indexOf(String str)
-
public String substring(int start,int end)
返回一个从start开始到end结束的左闭右开的子字符串
原字符串s1没有变化
String s2 = s1.substring(2, 4);
System.out.println(s1.length());//5
System.out.println(s2);//cb -
public int length()
-
public char charAt(int n)
-
public void setChatAt(int n ,char ch)
总结:
增:append(xxx)
删:delete(int start,int end)
改:setChatAt(int n ,char ch)/replace(int start,int end,String str)
查:charAt(int n)
插:insert(int offset,xxx)
长度:length();
遍历:for()+charAt()/toString()
String、StringBuffer、StringBuilder三者效率:
StringBuilder>StringBuffer>String
String、StringBuffer、StringBuilder之间的转换:
-
String--->StringBuffer、StringBuilder:
调用StringBuffer、StringBuilder的构造器
new StringBuffer(String str);
-
StringBuffer、StringBuilder--->String:
①调用String的构造器
②StringBuffer、StringBuilder的toString()方法
JDK8之前的日期时间API测试
-
System类中的currentTimeMillis()
用来返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差
称为时间戳
此方法适于计算时间差
long time = System.currentTimeMillis();
System.out.println(time);//1633966657021
-
Date类
-
两个构造器的使用:java.util.Date类
-
构造器一:Date();
Date date1 = new Date();
System.out.println(date1.toString());
//Mon Oct 11 23:50:11 CST 2021
-
构造器二:创建指定毫秒数的Date对象
1633967701698L
Date date2 = new Date(1633967701698l);
System.out.println(date2.toString());
//Mon Oct 11 23:55:01 CST 2021
还有|------java.sql.Date类
-
两个方法的使用
-
toString():显示当前的年月日时分秒
-
getTime():获取当前Date对象的毫秒数(时间戳)
System.out.println(date1.getTime());//1633967701698
-
java.sql.Date对应着数据库中的日期类型的变量
如何实例化:创建java.sql.Date对象
java.sql.Date date3 = new java.sql.Date(345678368494L);
System.out.println(date3);
//1980-12-15只打印年月日
-
sql.Date----->util.Date对象:多态
-
util.Date----->sql.Date对象p470
情况一:强转√
Date date4=new java.sql.Date(5678976534567L);
java.sql.Date date5=(java.sql.Date)date4;
情况二:
Date date6=new Date();
java.sql.Date date7=new java.sql.Date(date6.getTime());
//用getTime()方法找到time,把毫秒数扔到构造器里作为参数
习题
String类
例子:
-
代表字符串,使用一对“”引起来表示
-
是一个final类,不可被继承,代表不可变的字符序列
-
String实现了Serializable接口:表示字符串是支持序列化的(IO)
实现了Comparable接口:表示String可以比较大小
-
String内部定义了final char[] value用于储存字符串数据
-
通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串声明再字符串常量池中
String s1="abc";//字面量的定义方式String s2="abc"; -
字符串常量池中是不会存储相同内容的字符串:
使用String类的equals()比较,返回true的字符串
-
String代表了一个不可变的字符串序列,简称:不可变性,体现:
-
当对字符串重新赋值时,需要重写指定的内存区域赋值,不能使用原有的value进行赋值
String s1="abc";
String s2="abc";
s1="hello"; -
当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值
String s3="abc";
s3+="def";
System.out.println(s3);//abccdef -
当调用String的replace( )方法修改指定字符或字符串时,也需要重新指定内存区域赋值
String s4="abc";
String s5=s4.replace("a","m");
System.out.println(s4);//abc
System.out.println(s5);//mbc
-
String对象的创建
-
String的实例化方式:
-
通过字面量定义的方式
-
通过new+构造器的方式
//通过字面量定义的方式:
// 此时的s1和s2数据JavaEE声明在方法区中的字符串常量池中
String s1="javaEE";
String s2="javaEE";
//通过new+构造器的方式:
// 此时的s1和s2保存的地址值,是数据在堆空间中开辟空间以后对应的地址值
String s3=new String("javaEE");
String s4=new String("javaEE");
System.out.println(s1 == s2);//true
System.out.println(s1 == s3);//false
System.out.println(s1 == s4);//false
System.out.println(s3 == s4);//false
Person p1=new Person("Tom",12);
Person p2=new Person("Tom",12);
System.out.println(p1.name.equals(p2.name));//true
System.out.println(p1.name==p2.name);//true
-
面试题:
String s = new String("abc");方式创建对象,在内存中创建了几个对象?
两个:一个是在堆空间中new结构,另一个是char[ ]对应的常量池中的数据:“abc”
String s1="JavaEE";
String s2="hadoop";//基本
String s3="JavaEEhadoop";
String s4="JavaEE"+"hadoop";
String s5=s1+"hadoop";
String s6="JavaEE"+s2;
String s7=s1+s2;
System.out.println(s3 ==s4);//true
System.out.println(s3 =s5);//false
System.out.println(s3 =s6);//false
System.out.println(s3 =s7);//false
System.out.println(s5 =s6);//false
System.out.println(s5 =s7);//false
System.out.println(s6 =s7);//false
-
结论:
-
常量与常量的拼接结果在常量池,且常量池中不会存在相同内容的常量
-
只要其中有一个变量,结果就在堆中
-
如果拼接的结果调用intern()方法,返回值就在常量池中
String s8=s5.intern();//返回值得到的s8是常量池中已经存在的“JavaEEhadoop”
System.out.println(s3==s8);//true
补充:final
-
面试题:Java值传递
jdk1.6:字符串常量池存储在方法区(永久区)
jdk1.7:字符串常量池存储在堆空间
jdk1.8:字符串常量池存储在方法区(元空间)
String常用方法1
-
int length()
返回字符串的长度:return value.length
-
char charAt(int index)
返回某索引处的字符:return value[index]
String s1="helloworld";
System.out.println(s1.length());//10
System.out.println(s1.charAt(0));//h
System.out.println(s1.charAt(9));//d
System.out.println(s1.charAt(10));//越界注意下标长度不要越界
-
boolean isEmpty()
判断是否为空字符串:return value.length==0
(结果为true/false)
String s2="";
System.out.println(s2.isEmpty());//true -
String toLowerCase()
使用默认语言环境,将String中所有字符转换为小写
String s1="HelloWorld";
String s2=s1.toLowerCase(Locale.ROOT);//返回值接收为s2
System.out.println(s1);//HelloWorld,s1不可变,仍为原来字符串
System.out.println(s2);
//helloworld,改成小写以后字符串 -
String toUpperCase()
使用默认语言环境,将String中所有字符转换为大写
-
String trim()
返回字符串的副本,忽略前导空白和尾部空白(中间空格不变)
String s3=" he llo world ";
System.out.println("--"+s3+"--");
//-- he llo world --
System.out.println("--"+s3.trim()+"--");
//--he llo world-- -
boolean equals(Object obj)
比较字符串内容是否相同
-
boolean equalsIgnoreCase(String anotherString)
与equals方法类似,忽略大小写
String s1="HelloWorld";
String s2="helloworld";
System.out.println(s1.equals(s2));//false
System.out.println(s1.equalsIgnoreCase(s2));//true -
String concat(String str)
将指定的字符串连接到此字符串的结尾,等价于用“+”
String s3="abc";
String s4 = s3.concat("def");
System.out.println(s4);//abcdef -
int compareTo(String anotherString)
比较两个字符串的大小
String s5="abc";
String s6=new String("abe");
System.out.println(s5.compareTo(s6));//-2
//a是97,e是101
//涉及到字符串排序 -
String substring(int beginIndex)
返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个字符串
取出一个子字符串
String s7="北京尚硅谷教育";
String s8 = s7.substring(2);
System.out.println(s7);
//北京尚硅谷教育
System.out.println(s8);
//尚硅谷教育 -
String substring(int beginIndex,int endIndex)
返回一个新的字符串,它是此字符串的从beginIndex开始截取到endIndex(不包含)的一个字符串
[左闭右开)
String s7="北京尚硅谷教育";
String s9 = s7.substring(2, 5);//尚硅谷
String常用方法2
-
boolean endsWith(String suffix)
测试此字符串是否以指定的后缀结束
String str1="helloworld";
boolean b1=str1.endsWith("ld");
System.out.println(b1);//true -
boolean startsWith(String prefix)
测试此字符串是否以指定的前缀开始
String str1="helloworld";
boolean b2= str1.startsWith("He");
System.out.println(b2);//false -
boolean startsWith(String prefix,int toffset)
测试此字符串从指定索引开始的字符串是否以指定的前缀开始
从第2个开始,以"ll"开始(√)
String str1="helloworld";
boolean b3 = str1.startsWith("ll",2);
System.out.println(b3);//true
-
boolean contains(CharSequence s )
当且仅当此字符串包含指定的char值序列时,返回true
String str1="helloworld";
String str2="wo";
System.out.println(str1.contains(str2));//true -
int indexOf(String str)
返回指定子字符串在此字符串中第一次出现处的索引
String str1="helloworld";
System.out.println(str1.indexOf("lo"));//3
System.out.println(str1.indexOf("lol"));//-1:未找到的规定返回-1 -
int indexOf(String str, int fromIndex)
返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
从5开始找
String str1="helloworld";
System.out.println(str1.indexOf("lo",5));//-1 -
int lastIndexOf(String str)
返回指定子字符串在此字符串中最右边出现处的索引
0 1 2 3 4 5 6 7 8 9 10依旧从前往后数
h e l l o r w o r l d
String str3="hellorworld";
System.out.println(str3.lastIndexOf("or"));//7 -
int lastIndexOf(String str, int fromIndex)
返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索
0 1 2 3 4 5 6|7 8 9 10
h e l l o r w o r l d
String str3="hellorworld";
System.out.println(str3.lastIndexOf("or",6));//4
-
什么情况下,indexOf(str)和lastIndexOf(str)返回值相同?
情况一:存在唯一的一个str
情况二:不存在str
String常用方法3
替换-------------------------------------------------
-
String replace(char oldChar,char newChar)
返回一个新的字符串,他是通过newChar替换此字符串中出现的所有oldChar得到的
全改
String str1="北京尚硅谷教育北京";
String str2 =str1.replace('北', '东');
System.out.println(str1);//北京尚硅谷教育北京
System.out.println(str2);//东京尚硅谷教育东京 -
String replace(CharSequence target, CharSequence replacement)
使用指定的字面值替换序列替换此字符串所用匹配字面值目标序列的字符串
String str1="北京尚硅谷教育北京";
String str3 = str1.replace("北京", "上海");
//上海尚硅谷教育上海
-
String replaceAll(String regex:正则, String replacement)
使用给定的replacement替换此字符串所有匹配给定的正则表达式的子字符串
-
String replaceFirst(String regex, String replacement)
使用给定的replacement替换此字符串匹配给定的正则表达式的第一个子字符串
匹配(了解)--------------------------------------------
-
boolean matches(String regex)
告知此字符串是否匹配给定的正则表达式
切片(了解)--------------------------------------------
-
String[] split(String regex)
根据给定正则表达式的匹配拆分此字符串
-
String[] split(String regex, int limit)
根据匹配给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中
复习:
1、String转换基本数据类型、包装类
涉及到String类与其他结构之间的转换
String与基本数据类型和包装类之间的转换
-
String---->基本数据类型、包装类:
调用包装类的静态方法:parseXxx(str)
String str1="123";
int num=Integer.parseInt(str1); -
基本数据类型、包装类---->String
调用String重载的valueOf(xxx)
String str2 = String.valueOf(num);//"123"
//或
String str2=num+"";
2、String与字符数组转换
String与char[]之间的转换
-
String---->char[]:调用String的toCharArray()方法
str.toCharArray()
char[] charArray =
str2.toCharArray();
for (int i = 0; i <
charArray.length; i++) { System.out.println(charArray[i]);//输出charArray数组元素
}
-
char[]---->String:调用String的构造器
new String(arr);char[] arr=new char[]{'h','e','l','l','o'};
String str3 = new String(arr);
//new String(arr);
System.out.println(arr);//hello
3、String与byte[]之间的转换
-
String---->byte[],编码
调用String的getBytes()方法
String str1="abc123";
byte[] bytes = str1.getBytes();
System.out.println(Arrays.toString(bytes));
//[97, 98, 99, 49, 50, 51]
编码:字符串---->字节(看得懂-->看不懂)
解码:编码的逆过程 字节---->字符串
-
byte[]---->String,解码
调用String的构造器
String str2 = new String(bytes);
System.out.println(str2);//abc123中国
String str3 = new String(gbks);
System.out.println(str3);//abc123�й�出现乱码:解析时没有用gbk,编码集和解码集不一致
指定后没有乱码:
String gbk = new String(gbks, "gbk");
System.out.println(gbk);//abc123中国
说明:解码时,要求解码使用的字符集必须与编码时使用的字符集一致
StringBuffer类
关于 StringBuffer和 StringBuilder的使用
String、StringBuffer、StringBuilder三者异同:
String:不可变的字符序列;底层使用char[]存储
StringBuffer:可变的字符序列,线程安全的,效率低;底层使用char[]存储
StringBuilder:可变的字符序列,jdk5.0新增的,线程不安全的,效率高;底层使用char[]存储
源码分析:
String str=new String();//new char[0];
String str1=new String("abc"); //new char[]{'a','b','c'};
StringBuffer sb1=new StringBuffer(); //char[] value=new char[16];
相当于底层创建了一个长度为16的数组
sb1.oppend('a');//value[0]='a';
//相当于value首位置赋值为a,
sb1.oppend('b');//value[1]='b';
可变:可以在现有的加
StringBuffer str2=new StringBuffer("abc");//char[] value=new char["abc".length()+16]
每次造完后会额外空出16个
问题1:
StringBuffer str2=new StringBuffer();
System.out.println(sb1.length());//0
//
StringBuffer str2=new StringBuffer("abc");
System.out.println(sb1.length());//3
问题2:
扩容问题:如果要添加的数据底层数据盛不下了,那就需要扩容底层数组
默认情况下,扩容为原来的2倍+2,同时将原有数组的元素复制到新的数组中
指导意义:开发中使用:StringBuffer(int capacity)或StringBuilder(int capacity),指定容量,避免扩容复制
StringBuffer类的常用方法
-
StringBuffer append(xxx):
提供了很多的append()方法,用于进行字符串拼接
方法链:s.append().append().append()
StringBuffer s1=new StringBuffer("abc");
s1.append(1);
s1.append("1");
System.out.println(s1);//abc11 -
StringBuffer delete(int start,int end);
删除指定位置的内容
左闭右开
s1.delete(2,4);
System.out.println(s1);//ab1 -
StringBuffer replace(int start,int end,String str):
把[start,end)左闭右开位置替换为str
s1.replace(2,4,"hello");
System.out.println(s1);
//abhello1 -
StringBuffer insert(int offset,xxx):
在指定位置插入xxx
s1.insert(2,false);
System.out.println(s1);
//abfalsec11 -
StringBuffer reverse():
把当前字符序列逆转
s1.reverse();
System.out.println(s1);//11cba -
public int indexOf(String str)
-
public String substring(int start,int end)
返回一个从start开始到end结束的左闭右开的子字符串
原字符串s1没有变化
String s2 = s1.substring(2, 4);
System.out.println(s1.length());//5
System.out.println(s2);//cb -
public int length()
-
public char charAt(int n)
-
public void setChatAt(int n ,char ch)
总结:
增:append(xxx)
删:delete(int start,int end)
改:setChatAt(int n ,char ch)/replace(int start,int end,String str)
查:charAt(int n)
插:insert(int offset,xxx)
长度:length();
遍历:for()+charAt()/toString()
String、StringBuffer、StringBuilder三者效率:
StringBuilder>StringBuffer>String
String、StringBuffer、StringBuilder之间的转换:
-
String--->StringBuffer、StringBuilder:
调用StringBuffer、StringBuilder的构造器
new StringBuffer(String str);
-
StringBuffer、StringBuilder--->String:
①调用String的构造器
②StringBuffer、StringBuilder的toString()方法
JDK8之前的日期时间API测试
-
System类中的currentTimeMillis()
用来返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差
称为时间戳
此方法适于计算时间差
long time = System.currentTimeMillis();
System.out.println(time);//1633966657021
-
Date类
-
两个构造器的使用:java.util.Date类
-
构造器一:Date();
Date date1 = new Date();
System.out.println(date1.toString());
//Mon Oct 11 23:50:11 CST 2021
-
构造器二:创建指定毫秒数的Date对象
1633967701698L
Date date2 = new Date(1633967701698l);
System.out.println(date2.toString());
//Mon Oct 11 23:55:01 CST 2021
还有|------java.sql.Date类
-
两个方法的使用
-
toString():显示当前的年月日时分秒
-
getTime():获取当前Date对象的毫秒数(时间戳)
System.out.println(date1.getTime());//1633967701698
-
java.sql.Date对应着数据库中的日期类型的变量
如何实例化:创建java.sql.Date对象
java.sql.Date date3 = new java.sql.Date(345678368494L);
System.out.println(date3);
//1980-12-15只打印年月日
-
sql.Date----->util.Date对象:多态
-
util.Date----->sql.Date对象p470
情况一:强转√
Date date4=new java.sql.Date(5678976534567L);
java.sql.Date date5=(java.sql.Date)date4;
情况二:
Date date6=new Date();
java.sql.Date date7=new java.sql.Date(date6.getTime());
//用getTime()方法找到time,把毫秒数扔到构造器里作为参数
习题
JDK8中新日期时间API
Java比较器
System类
Math类
String类
例子:
-
代表字符串,使用一对“”引起来表示
-
是一个final类,不可被继承,代表不可变的字符序列
-
String实现了Serializable接口:表示字符串是支持序列化的(IO)
实现了Comparable接口:表示String可以比较大小
-
String内部定义了final char[] value用于储存字符串数据
-
通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串声明再字符串常量池中
String s1="abc";//字面量的定义方式String s2="abc"; -
字符串常量池中是不会存储相同内容的字符串:
使用String类的equals()比较,返回true的字符串
-
String代表了一个不可变的字符串序列,简称:不可变性,体现:
-
当对字符串重新赋值时,需要重写指定的内存区域赋值,不能使用原有的value进行赋值
String s1="abc";
String s2="abc";
s1="hello"; -
当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值
String s3="abc";
s3+="def";
System.out.println(s3);//abccdef -
当调用String的replace( )方法修改指定字符或字符串时,也需要重新指定内存区域赋值
String s4="abc";
String s5=s4.replace("a","m");
System.out.println(s4);//abc
System.out.println(s5);//mbc
-
String对象的创建
-
String的实例化方式:
-
通过字面量定义的方式
-
通过new+构造器的方式
//通过字面量定义的方式:
// 此时的s1和s2数据JavaEE声明在方法区中的字符串常量池中
String s1="javaEE";
String s2="javaEE";
//通过new+构造器的方式:
// 此时的s1和s2保存的地址值,是数据在堆空间中开辟空间以后对应的地址值
String s3=new String("javaEE");
String s4=new String("javaEE");
System.out.println(s1 == s2);//true
System.out.println(s1 == s3);//false
System.out.println(s1 == s4);//false
System.out.println(s3 == s4);//false
Person p1=new Person("Tom",12);
Person p2=new Person("Tom",12);
System.out.println(p1.name.equals(p2.name));//true
System.out.println(p1.name==p2.name);//true
-
面试题:
String s = new String("abc");方式创建对象,在内存中创建了几个对象?
两个:一个是在堆空间中new结构,另一个是char[ ]对应的常量池中的数据:“abc”
String s1="JavaEE";
String s2="hadoop";//基本
String s3="JavaEEhadoop";
String s4="JavaEE"+"hadoop";
String s5=s1+"hadoop";
String s6="JavaEE"+s2;
String s7=s1+s2;
System.out.println(s3 ==s4);//true
System.out.println(s3 =s5);//false
System.out.println(s3 =s6);//false
System.out.println(s3 =s7);//false
System.out.println(s5 =s6);//false
System.out.println(s5 =s7);//false
System.out.println(s6 =s7);//false
-
结论:
-
常量与常量的拼接结果在常量池,且常量池中不会存在相同内容的常量
-
只要其中有一个变量,结果就在堆中
-
如果拼接的结果调用intern()方法,返回值就在常量池中
String s8=s5.intern();//返回值得到的s8是常量池中已经存在的“JavaEEhadoop”
System.out.println(s3==s8);//true
补充:final
-
面试题:Java值传递
jdk1.6:字符串常量池存储在方法区(永久区)
jdk1.7:字符串常量池存储在堆空间
jdk1.8:字符串常量池存储在方法区(元空间)
String常用方法1
-
int length()
返回字符串的长度:return value.length
-
char charAt(int index)
返回某索引处的字符:return value[index]
String s1="helloworld";
System.out.println(s1.length());//10
System.out.println(s1.charAt(0));//h
System.out.println(s1.charAt(9));//d
System.out.println(s1.charAt(10));//越界注意下标长度不要越界
-
boolean isEmpty()
判断是否为空字符串:return value.length==0
(结果为true/false)
String s2="";
System.out.println(s2.isEmpty());//true -
String toLowerCase()
使用默认语言环境,将String中所有字符转换为小写
String s1="HelloWorld";
String s2=s1.toLowerCase(Locale.ROOT);//返回值接收为s2
System.out.println(s1);//HelloWorld,s1不可变,仍为原来字符串
System.out.println(s2);
//helloworld,改成小写以后字符串 -
String toUpperCase()
使用默认语言环境,将String中所有字符转换为大写
-
String trim()
返回字符串的副本,忽略前导空白和尾部空白(中间空格不变)
String s3=" he llo world ";
System.out.println("--"+s3+"--");
//-- he llo world --
System.out.println("--"+s3.trim()+"--");
//--he llo world-- -
boolean equals(Object obj)
比较字符串内容是否相同
-
boolean equalsIgnoreCase(String anotherString)
与equals方法类似,忽略大小写
String s1="HelloWorld";
String s2="helloworld";
System.out.println(s1.equals(s2));//false
System.out.println(s1.equalsIgnoreCase(s2));//true -
String concat(String str)
将指定的字符串连接到此字符串的结尾,等价于用“+”
String s3="abc";
String s4 = s3.concat("def");
System.out.println(s4);//abcdef -
int compareTo(String anotherString)
比较两个字符串的大小
String s5="abc";
String s6=new String("abe");
System.out.println(s5.compareTo(s6));//-2
//a是97,e是101
//涉及到字符串排序 -
String substring(int beginIndex)
返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个字符串
取出一个子字符串
String s7="北京尚硅谷教育";
String s8 = s7.substring(2);
System.out.println(s7);
//北京尚硅谷教育
System.out.println(s8);
//尚硅谷教育 -
String substring(int beginIndex,int endIndex)
返回一个新的字符串,它是此字符串的从beginIndex开始截取到endIndex(不包含)的一个字符串
[左闭右开)
String s7="北京尚硅谷教育";
String s9 = s7.substring(2, 5);//尚硅谷
String常用方法2
-
boolean endsWith(String suffix)
测试此字符串是否以指定的后缀结束
String str1="helloworld";
boolean b1=str1.endsWith("ld");
System.out.println(b1);//true -
boolean startsWith(String prefix)
测试此字符串是否以指定的前缀开始
String str1="helloworld";
boolean b2= str1.startsWith("He");
System.out.println(b2);//false -
boolean startsWith(String prefix,int toffset)
测试此字符串从指定索引开始的字符串是否以指定的前缀开始
从第2个开始,以"ll"开始(√)
String str1="helloworld";
boolean b3 = str1.startsWith("ll",2);
System.out.println(b3);//true
-
boolean contains(CharSequence s )
当且仅当此字符串包含指定的char值序列时,返回true
String str1="helloworld";
String str2="wo";
System.out.println(str1.contains(str2));//true -
int indexOf(String str)
返回指定子字符串在此字符串中第一次出现处的索引
String str1="helloworld";
System.out.println(str1.indexOf("lo"));//3
System.out.println(str1.indexOf("lol"));//-1:未找到的规定返回-1 -
int indexOf(String str, int fromIndex)
返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
从5开始找
String str1="helloworld";
System.out.println(str1.indexOf("lo",5));//-1 -
int lastIndexOf(String str)
返回指定子字符串在此字符串中最右边出现处的索引
0 1 2 3 4 5 6 7 8 9 10依旧从前往后数
h e l l o r w o r l d
String str3="hellorworld";
System.out.println(str3.lastIndexOf("or"));//7 -
int lastIndexOf(String str, int fromIndex)
返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索
0 1 2 3 4 5 6|7 8 9 10
h e l l o r w o r l d
String str3="hellorworld";
System.out.println(str3.lastIndexOf("or",6));//4
-
什么情况下,indexOf(str)和lastIndexOf(str)返回值相同?
情况一:存在唯一的一个str
情况二:不存在str
String常用方法3
替换-------------------------------------------------
-
String replace(char oldChar,char newChar)
返回一个新的字符串,他是通过newChar替换此字符串中出现的所有oldChar得到的
全改
String str1="北京尚硅谷教育北京";
String str2 =str1.replace('北', '东');
System.out.println(str1);//北京尚硅谷教育北京
System.out.println(str2);//东京尚硅谷教育东京 -
String replace(CharSequence target, CharSequence replacement)
使用指定的字面值替换序列替换此字符串所用匹配字面值目标序列的字符串
String str1="北京尚硅谷教育北京";
String str3 = str1.replace("北京", "上海");
//上海尚硅谷教育上海
-
String replaceAll(String regex:正则, String replacement)
使用给定的replacement替换此字符串所有匹配给定的正则表达式的子字符串
-
String replaceFirst(String regex, String replacement)
使用给定的replacement替换此字符串匹配给定的正则表达式的第一个子字符串
匹配(了解)--------------------------------------------
-
boolean matches(String regex)
告知此字符串是否匹配给定的正则表达式
切片(了解)--------------------------------------------
-
String[] split(String regex)
根据给定正则表达式的匹配拆分此字符串
-
String[] split(String regex, int limit)
根据匹配给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中
复习:
1、String转换基本数据类型、包装类
涉及到String类与其他结构之间的转换
String与基本数据类型和包装类之间的转换
-
String---->基本数据类型、包装类:
调用包装类的静态方法:parseXxx(str)
String str1="123";
int num=Integer.parseInt(str1); -
基本数据类型、包装类---->String
调用String重载的valueOf(xxx)
String str2 = String.valueOf(num);//"123"
//或
String str2=num+"";
2、String与字符数组转换
String与char[]之间的转换
-
String---->char[]:调用String的toCharArray()方法
str.toCharArray()
char[] charArray =
str2.toCharArray();
for (int i = 0; i <
charArray.length; i++) { System.out.println(charArray[i]);//输出charArray数组元素
}
-
char[]---->String:调用String的构造器
new String(arr);char[] arr=new char[]{'h','e','l','l','o'};
String str3 = new String(arr);
//new String(arr);
System.out.println(arr);//hello
3、String与byte[]之间的转换
-
String---->byte[],编码
调用String的getBytes()方法
String str1="abc123";
byte[] bytes = str1.getBytes();
System.out.println(Arrays.toString(bytes));
//[97, 98, 99, 49, 50, 51]
编码:字符串---->字节(看得懂-->看不懂)
解码:编码的逆过程 字节---->字符串
-
byte[]---->String,解码
调用String的构造器
String str2 = new String(bytes);
System.out.println(str2);//abc123中国
String str3 = new String(gbks);
System.out.println(str3);//abc123�й�出现乱码:解析时没有用gbk,编码集和解码集不一致
指定后没有乱码:
String gbk = new String(gbks, "gbk");
System.out.println(gbk);//abc123中国
说明:解码时,要求解码使用的字符集必须与编码时使用的字符集一致
StringBuffer类
关于 StringBuffer和 StringBuilder的使用
String、StringBuffer、StringBuilder三者异同:
String:不可变的字符序列;底层使用char[]存储
StringBuffer:可变的字符序列,线程安全的,效率低;底层使用char[]存储
StringBuilder:可变的字符序列,jdk5.0新增的,线程不安全的,效率高;底层使用char[]存储
源码分析:
String str=new String();//new char[0];
String str1=new String("abc"); //new char[]{'a','b','c'};
StringBuffer sb1=new StringBuffer(); //char[] value=new char[16];
相当于底层创建了一个长度为16的数组
sb1.oppend('a');//value[0]='a';
//相当于value首位置赋值为a,
sb1.oppend('b');//value[1]='b';
可变:可以在现有的加
StringBuffer str2=new StringBuffer("abc");//char[] value=new char["abc".length()+16]
每次造完后会额外空出16个
问题1:
StringBuffer str2=new StringBuffer();
System.out.println(sb1.length());//0
//
StringBuffer str2=new StringBuffer("abc");
System.out.println(sb1.length());//3
问题2:
扩容问题:如果要添加的数据底层数据盛不下了,那就需要扩容底层数组
默认情况下,扩容为原来的2倍+2,同时将原有数组的元素复制到新的数组中
指导意义:开发中使用:StringBuffer(int capacity)或StringBuilder(int capacity),指定容量,避免扩容复制
StringBuffer类的常用方法
-
StringBuffer append(xxx):
提供了很多的append()方法,用于进行字符串拼接
方法链:s.append().append().append()
StringBuffer s1=new StringBuffer("abc");
s1.append(1);
s1.append("1");
System.out.println(s1);//abc11 -
StringBuffer delete(int start,int end);
删除指定位置的内容
左闭右开
s1.delete(2,4);
System.out.println(s1);//ab1 -
StringBuffer replace(int start,int end,String str):
把[start,end)左闭右开位置替换为str
s1.replace(2,4,"hello");
System.out.println(s1);
//abhello1 -
StringBuffer insert(int offset,xxx):
在指定位置插入xxx
s1.insert(2,false);
System.out.println(s1);
//abfalsec11 -
StringBuffer reverse():
把当前字符序列逆转
s1.reverse();
System.out.println(s1);//11cba -
public int indexOf(String str)
-
public String substring(int start,int end)
返回一个从start开始到end结束的左闭右开的子字符串
原字符串s1没有变化
String s2 = s1.substring(2, 4);
System.out.println(s1.length());//5
System.out.println(s2);//cb -
public int length()
-
public char charAt(int n)
-
public void setChatAt(int n ,char ch)
总结:
增:append(xxx)
删:delete(int start,int end)
改:setChatAt(int n ,char ch)/replace(int start,int end,String str)
查:charAt(int n)
插:insert(int offset,xxx)
长度:length();
遍历:for()+charAt()/toString()
String、StringBuffer、StringBuilder三者效率:
StringBuilder>StringBuffer>String
String、StringBuffer、StringBuilder之间的转换:
-
String--->StringBuffer、StringBuilder:
调用StringBuffer、StringBuilder的构造器
new StringBuffer(String str);
-
StringBuffer、StringBuilder--->String:
①调用String的构造器
②StringBuffer、StringBuilder的toString()方法
JDK8之前的日期时间API测试
-
System类中的currentTimeMillis()
用来返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差
称为时间戳
此方法适于计算时间差
long time = System.currentTimeMillis();
System.out.println(time);//1633966657021
-
Date类
-
两个构造器的使用:java.util.Date类
-
构造器一:Date();
Date date1 = new Date();
System.out.println(date1.toString());
//Mon Oct 11 23:50:11 CST 2021
-
构造器二:创建指定毫秒数的Date对象
1633967701698L
Date date2 = new Date(1633967701698l);
System.out.println(date2.toString());
//Mon Oct 11 23:55:01 CST 2021
还有|------java.sql.Date类
-
两个方法的使用
-
toString():显示当前的年月日时分秒
-
getTime():获取当前Date对象的毫秒数(时间戳)
System.out.println(date1.getTime());//1633967701698
-
java.sql.Date对应着数据库中的日期类型的变量
如何实例化:创建java.sql.Date对象
java.sql.Date date3 = new java.sql.Date(345678368494L);
System.out.println(date3);
//1980-12-15只打印年月日
-
sql.Date----->util.Date对象:多态
-
util.Date----->sql.Date对象p470
情况一:强转√
Date date4=new java.sql.Date(5678976534567L);
java.sql.Date date5=(java.sql.Date)date4;
情况二:
Date date6=new Date();
java.sql.Date date7=new java.sql.Date(date6.getTime());
//用getTime()方法找到time,把毫秒数扔到构造器里作为参数
习题
字符串相关的类
例子:
-
代表字符串,使用一对“”引起来表示
-
是一个final类,不可被继承,代表不可变的字符序列
-
String实现了Serializable接口:表示字符串是支持序列化的(IO)
实现了Comparable接口:表示String可以比较大小
-
String内部定义了final char[] value用于储存字符串数据
-
通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串声明再字符串常量池中
String s1="abc";//字面量的定义方式String s2="abc"; -
字符串常量池中是不会存储相同内容的字符串:
使用String类的equals()比较,返回true的字符串
-
String代表了一个不可变的字符串序列,简称:不可变性,体现:
-
当对字符串重新赋值时,需要重写指定的内存区域赋值,不能使用原有的value进行赋值
String s1="abc";
String s2="abc";
s1="hello"; -
当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值
String s3="abc";
s3+="def";
System.out.println(s3);//abccdef -
当调用String的replace( )方法修改指定字符或字符串时,也需要重新指定内存区域赋值
String s4="abc";
String s5=s4.replace("a","m");
System.out.println(s4);//abc
System.out.println(s5);//mbc
-
String对象的创建
-
String的实例化方式:
-
通过字面量定义的方式
-
通过new+构造器的方式
//通过字面量定义的方式:
// 此时的s1和s2数据JavaEE声明在方法区中的字符串常量池中
String s1="javaEE";
String s2="javaEE";
//通过new+构造器的方式:
// 此时的s1和s2保存的地址值,是数据在堆空间中开辟空间以后对应的地址值
String s3=new String("javaEE");
String s4=new String("javaEE");
System.out.println(s1 == s2);//true
System.out.println(s1 == s3);//false
System.out.println(s1 == s4);//false
System.out.println(s3 == s4);//false
Person p1=new Person("Tom",12);
Person p2=new Person("Tom",12);
System.out.println(p1.name.equals(p2.name));//true
System.out.println(p1.name==p2.name);//true
-
面试题:
String s = new String("abc");方式创建对象,在内存中创建了几个对象?
两个:一个是在堆空间中new结构,另一个是char[ ]对应的常量池中的数据:“abc”
String s1="JavaEE";
String s2="hadoop";//基本
String s3="JavaEEhadoop";
String s4="JavaEE"+"hadoop";
String s5=s1+"hadoop";
String s6="JavaEE"+s2;
String s7=s1+s2;
System.out.println(s3 ==s4);//true
System.out.println(s3 =s5);//false
System.out.println(s3 =s6);//false
System.out.println(s3 =s7);//false
System.out.println(s5 =s6);//false
System.out.println(s5 =s7);//false
System.out.println(s6 =s7);//false
-
结论:
-
常量与常量的拼接结果在常量池,且常量池中不会存在相同内容的常量
-
只要其中有一个变量,结果就在堆中
-
如果拼接的结果调用intern()方法,返回值就在常量池中
String s8=s5.intern();//返回值得到的s8是常量池中已经存在的“JavaEEhadoop”
System.out.println(s3==s8);//true
补充:final
-
面试题:Java值传递
jdk1.6:字符串常量池存储在方法区(永久区)
jdk1.7:字符串常量池存储在堆空间
jdk1.8:字符串常量池存储在方法区(元空间)
String常用方法1
-
int length()
返回字符串的长度:return value.length
-
char charAt(int index)
返回某索引处的字符:return value[index]
String s1="helloworld";
System.out.println(s1.length());//10
System.out.println(s1.charAt(0));//h
System.out.println(s1.charAt(9));//d
System.out.println(s1.charAt(10));//越界注意下标长度不要越界
-
boolean isEmpty()
判断是否为空字符串:return value.length==0
(结果为true/false)
String s2="";
System.out.println(s2.isEmpty());//true -
String toLowerCase()
使用默认语言环境,将String中所有字符转换为小写
String s1="HelloWorld";
String s2=s1.toLowerCase(Locale.ROOT);//返回值接收为s2
System.out.println(s1);//HelloWorld,s1不可变,仍为原来字符串
System.out.println(s2);
//helloworld,改成小写以后字符串 -
String toUpperCase()
使用默认语言环境,将String中所有字符转换为大写
-
String trim()
返回字符串的副本,忽略前导空白和尾部空白(中间空格不变)
String s3=" he llo world ";
System.out.println("--"+s3+"--");
//-- he llo world --
System.out.println("--"+s3.trim()+"--");
//--he llo world-- -
boolean equals(Object obj)
比较字符串内容是否相同
-
boolean equalsIgnoreCase(String anotherString)
与equals方法类似,忽略大小写
String s1="HelloWorld";
String s2="helloworld";
System.out.println(s1.equals(s2));//false
System.out.println(s1.equalsIgnoreCase(s2));//true -
String concat(String str)
将指定的字符串连接到此字符串的结尾,等价于用“+”
String s3="abc";
String s4 = s3.concat("def");
System.out.println(s4);//abcdef -
int compareTo(String anotherString)
比较两个字符串的大小
String s5="abc";
String s6=new String("abe");
System.out.println(s5.compareTo(s6));//-2
//a是97,e是101
//涉及到字符串排序 -
String substring(int beginIndex)
返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个字符串
取出一个子字符串
String s7="北京尚硅谷教育";
String s8 = s7.substring(2);
System.out.println(s7);
//北京尚硅谷教育
System.out.println(s8);
//尚硅谷教育 -
String substring(int beginIndex,int endIndex)
返回一个新的字符串,它是此字符串的从beginIndex开始截取到endIndex(不包含)的一个字符串
[左闭右开)
String s7="北京尚硅谷教育";
String s9 = s7.substring(2, 5);//尚硅谷
String常用方法2
-
boolean endsWith(String suffix)
测试此字符串是否以指定的后缀结束
String str1="helloworld";
boolean b1=str1.endsWith("ld");
System.out.println(b1);//true -
boolean startsWith(String prefix)
测试此字符串是否以指定的前缀开始
String str1="helloworld";
boolean b2= str1.startsWith("He");
System.out.println(b2);//false -
boolean startsWith(String prefix,int toffset)
测试此字符串从指定索引开始的字符串是否以指定的前缀开始
从第2个开始,以"ll"开始(√)
String str1="helloworld";
boolean b3 = str1.startsWith("ll",2);
System.out.println(b3);//true
-
boolean contains(CharSequence s )
当且仅当此字符串包含指定的char值序列时,返回true
String str1="helloworld";
String str2="wo";
System.out.println(str1.contains(str2));//true -
int indexOf(String str)
返回指定子字符串在此字符串中第一次出现处的索引
String str1="helloworld";
System.out.println(str1.indexOf("lo"));//3
System.out.println(str1.indexOf("lol"));//-1:未找到的规定返回-1 -
int indexOf(String str, int fromIndex)
返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
从5开始找
String str1="helloworld";
System.out.println(str1.indexOf("lo",5));//-1 -
int lastIndexOf(String str)
返回指定子字符串在此字符串中最右边出现处的索引
0 1 2 3 4 5 6 7 8 9 10依旧从前往后数
h e l l o r w o r l d
String str3="hellorworld";
System.out.println(str3.lastIndexOf("or"));//7 -
int lastIndexOf(String str, int fromIndex)
返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索
0 1 2 3 4 5 6|7 8 9 10
h e l l o r w o r l d
String str3="hellorworld";
System.out.println(str3.lastIndexOf("or",6));//4
-
什么情况下,indexOf(str)和lastIndexOf(str)返回值相同?
情况一:存在唯一的一个str
情况二:不存在str
String常用方法3
替换-------------------------------------------------
-
String replace(char oldChar,char newChar)
返回一个新的字符串,他是通过newChar替换此字符串中出现的所有oldChar得到的
全改
String str1="北京尚硅谷教育北京";
String str2 =str1.replace('北', '东');
System.out.println(str1);//北京尚硅谷教育北京
System.out.println(str2);//东京尚硅谷教育东京 -
String replace(CharSequence target, CharSequence replacement)
使用指定的字面值替换序列替换此字符串所用匹配字面值目标序列的字符串
String str1="北京尚硅谷教育北京";
String str3 = str1.replace("北京", "上海");
//上海尚硅谷教育上海
-
String replaceAll(String regex:正则, String replacement)
使用给定的replacement替换此字符串所有匹配给定的正则表达式的子字符串
-
String replaceFirst(String regex, String replacement)
使用给定的replacement替换此字符串匹配给定的正则表达式的第一个子字符串
匹配(了解)--------------------------------------------
-
boolean matches(String regex)
告知此字符串是否匹配给定的正则表达式
切片(了解)--------------------------------------------
-
String[] split(String regex)
根据给定正则表达式的匹配拆分此字符串
-
String[] split(String regex, int limit)
根据匹配给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中
复习:
1、String转换基本数据类型、包装类
涉及到String类与其他结构之间的转换
String与基本数据类型和包装类之间的转换
-
String---->基本数据类型、包装类:
调用包装类的静态方法:parseXxx(str)
String str1="123";
int num=Integer.parseInt(str1); -
基本数据类型、包装类---->String
调用String重载的valueOf(xxx)
String str2 = String.valueOf(num);//"123"
//或
String str2=num+"";
2、String与字符数组转换
String与char[]之间的转换
-
String---->char[]:调用String的toCharArray()方法
str.toCharArray()
char[] charArray =
str2.toCharArray();
for (int i = 0; i <
charArray.length; i++) { System.out.println(charArray[i]);//输出charArray数组元素
}
-
char[]---->String:调用String的构造器
new String(arr);char[] arr=new char[]{'h','e','l','l','o'};
String str3 = new String(arr);
//new String(arr);
System.out.println(arr);//hello
3、String与byte[]之间的转换
-
String---->byte[],编码
调用String的getBytes()方法
String str1="abc123";
byte[] bytes = str1.getBytes();
System.out.println(Arrays.toString(bytes));
//[97, 98, 99, 49, 50, 51]
编码:字符串---->字节(看得懂-->看不懂)
解码:编码的逆过程 字节---->字符串
-
byte[]---->String,解码
调用String的构造器
String str2 = new String(bytes);
System.out.println(str2);//abc123中国
String str3 = new String(gbks);
System.out.println(str3);//abc123�й�出现乱码:解析时没有用gbk,编码集和解码集不一致
指定后没有乱码:
String gbk = new String(gbks, "gbk");
System.out.println(gbk);//abc123中国
说明:解码时,要求解码使用的字符集必须与编码时使用的字符集一致
StringBuffer类
关于 StringBuffer和 StringBuilder的使用
String、StringBuffer、StringBuilder三者异同:
String:不可变的字符序列;底层使用char[]存储
StringBuffer:可变的字符序列,线程安全的,效率低;底层使用char[]存储
StringBuilder:可变的字符序列,jdk5.0新增的,线程不安全的,效率高;底层使用char[]存储
源码分析:
String str=new String();//new char[0];
String str1=new String("abc"); //new char[]{'a','b','c'};
StringBuffer sb1=new StringBuffer(); //char[] value=new char[16];
相当于底层创建了一个长度为16的数组
sb1.oppend('a');//value[0]='a';
//相当于value首位置赋值为a,
sb1.oppend('b');//value[1]='b';
可变:可以在现有的加
StringBuffer str2=new StringBuffer("abc");//char[] value=new char["abc".length()+16]
每次造完后会额外空出16个
问题1:
StringBuffer str2=new StringBuffer();
System.out.println(sb1.length());//0
//
StringBuffer str2=new StringBuffer("abc");
System.out.println(sb1.length());//3
问题2:
扩容问题:如果要添加的数据底层数据盛不下了,那就需要扩容底层数组
默认情况下,扩容为原来的2倍+2,同时将原有数组的元素复制到新的数组中
指导意义:开发中使用:StringBuffer(int capacity)或StringBuilder(int capacity),指定容量,避免扩容复制
StringBuffer类的常用方法
-
StringBuffer append(xxx):
提供了很多的append()方法,用于进行字符串拼接
方法链:s.append().append().append()
StringBuffer s1=new StringBuffer("abc");
s1.append(1);
s1.append("1");
System.out.println(s1);//abc11 -
StringBuffer delete(int start,int end);
删除指定位置的内容
左闭右开
s1.delete(2,4);
System.out.println(s1);//ab1 -
StringBuffer replace(int start,int end,String str):
把[start,end)左闭右开位置替换为str
s1.replace(2,4,"hello");
System.out.println(s1);
//abhello1 -
StringBuffer insert(int offset,xxx):
在指定位置插入xxx
s1.insert(2,false);
System.out.println(s1);
//abfalsec11 -
StringBuffer reverse():
把当前字符序列逆转
s1.reverse();
System.out.println(s1);//11cba -
public int indexOf(String str)
-
public String substring(int start,int end)
返回一个从start开始到end结束的左闭右开的子字符串
原字符串s1没有变化
String s2 = s1.substring(2, 4);
System.out.println(s1.length());//5
System.out.println(s2);//cb -
public int length()
-
public char charAt(int n)
-
public void setChatAt(int n ,char ch)
总结:
增:append(xxx)
删:delete(int start,int end)
改:setChatAt(int n ,char ch)/replace(int start,int end,String str)
查:charAt(int n)
插:insert(int offset,xxx)
长度:length();
遍历:for()+charAt()/toString()
String、StringBuffer、StringBuilder三者效率:
StringBuilder>StringBuffer>String
String、StringBuffer、StringBuilder之间的转换:
-
String--->StringBuffer、StringBuilder:
调用StringBuffer、StringBuilder的构造器
new StringBuffer(String str);
-
StringBuffer、StringBuilder--->String:
①调用String的构造器
②StringBuffer、StringBuilder的toString()方法

浙公网安备 33010602011771号