JAVA之String类

JAVA之String类,第1张

目录

String类的声明

创建String对象的四种方式

字符比较相等 

字符串的常量池问题 

字符串的不可变性 

StringBuilder和StringBuffer 

字符串的 *** 作 


String类的声明

JDK中的String类

  •  我们发现String类被final修饰,表示String类无法被继承,String类不存在子类,因为这样我们就可以保证所有人都用JDK的String类
  • 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对象的地址
  • 当常量池中没有这个对象,则将这个对象入池,并返回入池后的地址

 

字符串的不可变性 

概念:所谓字符串的不可变性,说的是引用指向的字符串对象的内容是不可变的的,而字符串的引用是可以改变的

  •  不是说字符串对象的内容是不可以变的吗,为什么最后str的内容变成了helloworld!,让我们看看内存中是如何变换的
  • 我们发现确实字符串对象的内容是不变的,当字符串字面常量第一次出现就会放在常量池中,str最后内容改变,只是指向了不同的字符串对象 

实现字符串不可变的原理

因为字符串的实质就是用字符串数组去存储,我们发现在String类中是一个私有属性,而且也没有提供修改内容的方法

如何去改变字符串的内容

  1. 在运行的时候通过反射破坏value数组的封装(但是不推荐这样)
  2. 更换使用StringBuilder或者StringBuffer类——>跟Stirng已经不是一个类型了

StringBuilder和StringBuffer 

这两个类的出现就是为了解决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其他 *** 作 

 

 写一个方法将字符串的首字母大写

总结:对字符串的任意 *** 作,对原字符串都不会有任何改变 

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/890796.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-14
下一篇 2022-05-14

发表评论

登录后才能评论

评论列表(0条)

保存