String
String结构剖析
1.String对象是用来保存字符串的,也就是一组字符序列
2.字符串常量是用双引号括起来的字符序列例如"你好","12.97"等
3.字符串使用Unicode编码,一个字符(不管是汉字还是字母)占两个字节
4.String有多个构造器
比较常用的有
5.String类实现了接口Serializable(可以串行化:在网络上传输)
和接口Comparable(可以进行大小比较)
6.String是final类,不能被其他的类继承
7. String中有一个属性private final char value[];用于存放字符串内容,实际上字符串的本质还是字符串数组,value[]就是那个对应的字符串数组
8. value是final类型,不能更改(是他指向不可修改,而不是指向的里面的内容不可修改)
继承关系![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/0306709572d96a771468612e59aca9c4.png)
String创建剖析
//方式1直接赋值
String s="jack";
//方式2(构造器),有多种
String s=new String("jack");
还有一中字符数组转成String形式
char a[]={a,b,c,d,e,f};
String c=new String(a);
两种机制不同
方式1
先从常量池找是否有jack的数据空间,有直接指向,没有,创建再指向
最后指向常量池的空间地址
方式2
先在堆中创建空间,里面维护value属性,指向常量池jack的空间,如果常量池中没有"jack",重新创建,如果有直接通过value指向,最终指向的是堆中的空间地址
两种方式的内存分布图
例题
例题1
TTTF
例题2
第一句和第二句肯定分别在常量池创建了两个String对象
分析String c=a+b;
所以最后是在常量池中创建了三个对象
规律
String做参传递修改的坑
本题还是很精髓的
输出是hspandhava
我来解析一下
主方法调用change方法
在栈中创建空间,str和char ch[]都有对应的变化
因为一个对象有关数组所以但是引用传递(地址传递)
str="java";//这句话分析至关重要
在change方法单独创建的str指向堆中str指向的value[]数组
但是警告str=“java”;
是改变了栈中str的指向,在常量池新建了java,然后栈中str指向java和堆中那个没有关系了
没有改变堆中的str指向的value(hsp)
然后
ch[0]='h';
引用传递实实在在改变了堆中ch指向的java里面的j变为了h
最后等change方法结束
str并没有改变,但是ch改变了
所以输出的是
hspandhava
总结
String类型传递
String类型比较特殊,因为String类型是不可变的,如果形参经过操作修改的话,常量池中会开辟一个新的内存空间来存储修改后的数据(直接使用双引号声明出来的String对象会直接存储在常量池中)。形参的改变对实参也没有影响。结果和值传递一样,但是值传递不会开辟新的内存空间。
public static void main(String[] args) {
String n="a";
init(n);
}
public static void init(String m) {
System.out.println("改变前"+m);
m="aaa";
System.out.println("改变后"+m);
}
//输出
改变前a
改变后aaa
String中的常用方法
1.intren()方法
返回值是和你调用字符串内容相同,常量池那个地址中那个字符串
比如上面那个s2.intern(),返回值是Ox99对应的hsp
如果没有与调用字符串内容相同的,则将调用字符串添加到池中,并返回此字符串的引用
2.equals(字符串对象或字符串常量)
区分大小写,判断内容是否相等,相对返回true,不相等返回false
3.equalslgnoreCase(字符串对象或字符串常量)
忽略大小写判断内容是否相等
4.length()
获取字符个数,得到字符串的长度
5.indexOf(一个字符或者字符常量或者字符串)!!!
可以用来判断字符串子串
获取字符第一次在字符串中出现的索引,索引从0开始,如果找不到,返回-1
6.lastIndexOf(一个字符或者字符常量或者字符串)
获取字符最后一次在字符串中出现的索引,索引从0开始,如果找不到,返回-1
都是取第一个
7.substring()
截取指定范围内的子串
这个方法两个重载
一个是substring(int a)
这个写法是返回从索引a到最后的字符串
一个是substring(int a,int b)
这个写法返回的是从索引a到索引b-1的字符串
[a,b)这样
8.trim()
去前后空格
9.charAt
获取索引处的字符注意不能使用Str[index]这种方式
Sting.charAt(0)才能取出第一个字符
下面一截图的方式展现
poem.split(“,”)返回一个,为分隔符的String数组存储被分割的字符串
10.String.toUpperCase()返回,字符串内的字符全转为大写的结果
11.String.toLowerCase()返回,全部小写后的结果
compareTo比较机制
1.先比较长度
长度不同返回a.length()-b.length()
2.再比较字符
长度相同从首个字母往后看,比较第一个不同的字母
用a的第一个不同字母减去b的第一个不同字母(unicode码相减)
2.如果内容完全相同,返回0
format()格式化字符串
这样可以做到修改里面的一个属性,就修改整条信息
其实上面的两条语句
算为
String info2=String.format("我的姓名是%s,年龄是%d,成绩是%.2f性别是%c。希望大家喜欢我。",name,age,score,gender);
//与c语言类似的写法
String.valueOf() 这个参数多载的方法
有下列几种
String.valueOf(boolean b) : 将 boolean 变量 b 转换成字符串
String.valueOf(char c) : 将 char 变量 c 转换成字符串
String.valueOf(char[] data) : 将 char 数组 data 转换成字符串
String.valueOf(char[] data, int offset, int count) :
将 char 数组 data 中 由 data[offset] 开始取 count 个元素 转换成字符串
String.valueOf(double d) : 将 double 变量 d 转换成字符串
String.valueOf(float f) : 将 float 变量 f 转换成字符串
String.valueOf(int i) : 将 int 变量 i 转换成字符串
String.valueOf(long l) : 将 long 变量 l 转换成字符串
String.valueOf(Object obj) : 将 obj 对象转换成 字符串, 等于 obj.toString()
用法如:
int i = 10;
String str = String.valueOf(i);
这时候 str 就会是 “10”
StringBuffer
StringBuffer结构剖析
基本介绍
继承结构
package com.hansp.string_;
public class StringBuffer01 {
public static void main(String[] args) {
//1.StringBuffer的直接父类是AbstractStringBuilder
//2.实现Serializable即StringBuffer的对象可以串行化
//3.在父类中AbstractStringBuilder有属性char[]value,不是final
//该value数组存放我们的字符串内容,存放在堆中,不是常量池
//4.StringBuffer也是一个final类,不可被继承
StringBuffer stringBuffer = new StringBuffer();
}
}
StringvsStringBuffer
package com.hansp.string_;
public class StringBuffer01 {
public static void main(String[] args) {
//1.StringBuffer的直接父类是AbstractStringBuilder
//2.实现Serializable即StringBuffer的对象可以串行化
//3.在父类中AbstractStringBuilder有属性char[]value,不是final
//该value数组存放我们的字符串内容,存放在堆中,不是常量池
//4.StringBuffer也是一个final类,不可被继承
//5.因为StringBuffer字符内容是存在char[] value,所以在变化的时候
//不用每次的更换地址(创建新的对象),所以其效率高于String
StringBuffer stringBuffer = new StringBuffer();
}
}
StringBuffer的构造器![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/22de5eba385ad5ff445192022bb3d0d8.png)
1和3和4常用
1 char[]默认长度16
3 char[]长度是你输入的形参
4 char[]长度是形参字符串的长度+16
注意
StringBuffer类没有重写equals方法
你写equals和==效果一样
都是判断是不是指向同一个对象
可以先转换成Sting再equals
String和StringBuffer相互转换
package com.hansp.string_;
public class StringBuffer01 {
public static void main(String[] args) {
//String->StringBuffer
//方式1
//返回的是StingBuffer对象,对str没有影响
String str="hello";
StringBuffer stringBuffer1 = new StringBuffer(str);
//方式2
//使用append方法,也是对str没有影响,返回值是StringBuffer
StringBuffer stringBuffer = new StringBuffer();
StringBuffer append = stringBuffer.append(str);
//StringBuffer->String
StringBuffer stringBuffer2 = new StringBuffer("小袁");
//方式1
//使用StringBuffer的toString方法
String s=stringBuffer2.toString();
//方式2
//使用构造器
String s1=new String(stringBuffer2);
}
}
StringBuffer常用方法
1.append()
2.delete(int start,int end)
包含start不包含end
如果你想要全删除可以用delete(0,StringBuffer.length())
3.replace(int start,int end,String a)
4.indexOf()
5.insert()
6.length()
也有CharAt()等方法
StringBuilder
StringBuilder基本介绍
一般用在单线程,和Buffer不同Buffer用在多线程
继承关系
常用方法
和StringBuffer一致
reverse()
反转字符串(自己修改的同时也有返回值)
String和StringBuffer和StringBuilder