目录
String类的声明
创建String对象的四种方式
字符比较相等
字符串的常量池问题
字符串的不可变性
StringBuilder和StringBuffer
字符串的 *** 作
String类的声明
创建String对象的四种方式JDK中的String类
- 我们发现String类被final修饰,表示String类无法被继承,String类不存在子类,因为这样我们就可以保证所有人都用JDK的String类
- String是引用类型,是一个类
字符串的比较
- 1直接赋值(语法糖)String s="hello String";
- 2通过构造方法产生对象 String s=new String("hello String");
- 3通过字符数组产生 char []date=new char[]{1,2,3,4}; String s=new String(date);
- 4通过String的静态方法valueOf(任意数据类型)——>转换为字符串
String作为类
字符串的常量池问题所有的引用数据类型在比较是否相等的时候,都是使用equals,作为JDK的常用类,已经覆写过了equals方法,大家直接使用即可
equalsIgnoreCase
一个使用时的注意点
这两种方式,肯定是第二种方式比较好,因为第一种方式可能会有空指针的风险,牵扯到用户输入的时候一定要做判空处理
字符串的不可变性我们来看一个现象
我们发现输出的是 true,但是按常理来说,==比较的是两个对象的地址,str1和str2是两个对象,不应该地址不一样吗?由此引出了常量池的知识
- 在我们使用直接赋值法来产生字符串对象的时候,JVM会维护一个字符串的常量池,这个常量池也是在堆中
- 当这个对象在常量池中不存在的时候,那么会在常量池中直接产生这个对象
- 当使用直接赋值法产生字符串对象,发现该对象引用指向的内容在常量池中已经存在,那此时不会再产生新对象,而是直接复用常量池中已经有的对象
其他方式产生
当我们用构造方法产生字符串对象,因为程序是从右到左执行,s1因为第一次出现了字面常量"hello",所以会先在常量池中产生一个对象,然后会在堆区产生一个字符串对象,后面的s2,s3也会分别产生各自的字符串对象,并不会去指向常量池中的字符串对象
池的思想
也就是共享设计模式,为了节省空间(因为内存十分宝贵),字符串产生之后大部分情况都是用来进行输出处理,只打印,一个对象就够了,数据库的连接池和线程池都是这样的思想
手动入池
因为只有直接赋值的方法会自动入池,如果我们使用别发方法产生字符串对象,也想入池,JDK提供了intern()方法
- 当常量池中已经有了这个对象,则不会在常量池中产生新的对象,并且返回常量池中的String对象的地址
- 当常量池中没有这个对象,则将这个对象入池,并返回入池后的地址
StringBuilder和StringBuffer概念:所谓字符串的不可变性,说的是引用指向的字符串对象的内容是不可变的的,而字符串的引用是可以改变的
- 不是说字符串对象的内容是不可以变的吗,为什么最后str的内容变成了helloworld!,让我们看看内存中是如何变换的
- 我们发现确实字符串对象的内容是不变的,当字符串字面常量第一次出现就会放在常量池中,str最后内容改变,只是指向了不同的字符串对象
实现字符串不可变的原理
因为字符串的实质就是用字符串数组去存储,我们发现在String类中是一个私有属性,而且也没有提供修改内容的方法
如何去改变字符串的内容
- 在运行的时候通过反射破坏value数组的封装(但是不推荐这样)
- 更换使用StringBuilder或者StringBuffer类——>跟Stirng已经不是一个类型了
字符串的 *** 作这两个类的出现就是为了解决String不可变,因为如果频繁的对字符串进行拼接,会不断产生新的对象,比较消耗内存,这两个类的字符串内容是可以变的
使用提供的append方法来增加字符串的内容,这里不会产生新的对象,一种指向着一个对象
String和StringBuilder的相互转换
一些其他的 *** 作
因为可以改变字符串的内容,所以拥有一些String不具备的功能
- 字符串的反转 reserve()
- 删除指定范围的数据 delete(int start,int end),Java中的范围基本都是左闭右开 [start,end)
- 插入 *** 作 insert(int start,各中数据类型),插入数据的起始索引是start
三个类的区别
- String相比于StringBuilder和StringBuffer是其字符串的内容是不可变的
- StringBuffer是用于线程安全的 *** 作,性能差一点,StringBuilder的线程安全较差,但是性能好一点,其 *** 作都是一样的
1字符串的比较前两种方法已经介绍过了,因为String也继承了Comparable接口,所以也覆写了CompareTo方法,字符串的ComparaTo方法按照字符串内部数组进行ASCII的比较
从开头比较每一个字符,当遇到第一个字符不一样的时候,就返回str1字符的ASCII-str2字符的ASCII的值,如果都一样,就返回0
- 字符串的比较大小规则, 总结成三个字 "字典序" 相当于判定两个字符串在一本词典的前面还是后面. 先比较第一 个字符的大小(根据 unicode 的值来判定), 如果不分胜负, 就依次比较后面的内容
2字符串和字符的转换
这些 *** 作,其被 *** 作的字符串的内容是没有变的,严格遵循字符串不变性
题目:如何判断一个字符串是不是纯数字
处理思想 :就是在循环中找到一个反例,就可以直接return false;
3字符串于字节转换将字符串保存到文件中,或者是通过网络传输都是需要将字符串转换为字节,需要用到字节数组
4字符串查找 *** 作
5字符串替换 *** 作这里的替换,所有的 *** 作对原字符串不会造成改变。而是产生了新的字符串
6字符串的拆分 *** 作按limit限制,这个数组的长度就是2
特殊字符的分割
- 1. 字符"|","*","+"都得加上转义字符,前面加上"\".
- 2. 而如果是".",那么就得写成"\."
- 3. 如果一个字符串中有多个分隔符,可以用"|"作为连字符.
7字符串的截取 *** 作不会改变原来的字符串,只会产生新的字符串
8其他 *** 作
写一个方法将字符串的首字母大写
总结:对字符串的任意 *** 作,对原字符串都不会有任何改变
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)