一. 首先了解一下String类的两种实例化方式:直接赋值和通过构造方法赋值
1.直接赋值:String str=“Hello”;对象保存在堆上字符串常量池中。
2.通过构造方法赋值:String str=new String(“Hello”);对象在堆内存中新开辟了一个空间。
二. 两种实例化模式的区别 (推荐使用直接赋值的方式实例化String对象)
1.直接赋值:
String类采用共享式设计模式,这是因为JVM底层会维护一个字符串常量池(实质上就是字符串数组),若采用直接赋值的形式进行String类的实例化操作。那么该对象会自动保存在对象池中。如果下次即系统采用直接赋值的形式,首先在对象池中查看是否有指定内容,若有,直接引用,若没有,产生新的对象后入池。
2.采用构造方法:
采用构造方法实例化的String对象不会入池
输出结果:false
结果分析:采用构造方法实例化操作后的值不会保存在常量池中,第一次实例后在堆上开辟新空间但没有入池,第二次实例化时,JVM在对象池中找不到指定字符串内容,从而产生新对象后入池,两次实例化对象的地址不同。
可以通过调用String中的intern()方法手工入池:
public native String intern();本地方法
输出结果:true
3.使用构造方法实例化String对象会产生两块内存空间,其中一块为垃圾空间,不会入池
例如:String str=new String(“hello”);
会产生两块内存空间,首先会在堆上产生hello匿名对象,不会入池,是垃圾空间
new后会再次产生一块新的空间,str指向最新的内存空间
三.字符串比较(https://mp.youkuaiyun.com/postedit/89513087详情请看这篇博客)
“==”比较的是两个操作数的值,对于基本数据类型来说比较的是值的大小,对于引用类型而言,比较的是两者指向的堆内存地址是否相同。
当我们要比较字符串内容是否相等时,使用equals()方法,String类覆写了基类Object类中的equals方法。
四. 字符串常量是String类的匿名对象
字符串常量:使用“ ”括起来的内容。所有字符串常量都是String的匿名对象。
在进行指定字符串内容与字符串对象比较时,将字符串常量写在equals前,避免NullPointerException
通过下面代码演示:
public class Test{
public static void main(String[] args) {
String str=null;
//错误范例 将字符串对象放在字符串指定内容前面
// System.out.println(str.equals("hello"));
//正确示范
System.out.println("hello".equals(str));
}
}
五. 字符串不可变更
字符串常量不可变,用"+"拼接操作,改变的是栈的指向
字符串的+操作不要出现太多次,会产生大量垃圾空间
六. 字符与字符串(char与String的相互转换)
字符串就是一个字符数组
-
将char[]->String
调用String的构造方法实现
public String(char value[]):将字符数组所有内容转为String
public String(char value[],int offset,int count):将字符数组部分转为字符串
-
String->char(String类中的方法)
public char charAt(int index):取得字符串指定索引的字符
public char[] toCharArray():将字符串全都转换为字符数组
面试题:
判断字符串是否全都由数字组成
思路:先将字符串全部转换为字符数组,然后遍历字符数组中的每个元素
七.String与字节的相互转换(String<->byte)
-
字节数组转换为字符串
构造方法
public String(byte value[])
public String(byte value[],int offset,int count) -
String->byte
public byte[] getBytes():将字符串全部转换为字节数组
public byte[] getBytes(String charSetName):将字符串以指定编码转为字节数组
八.字符串比较
boolean equals():区分大小写比较
boolean equalsIgnoreCase():不区分大小写比较
int compareTo(String anotherString):当碰到第一个不相等的字符时,终止比较,返回两个字符的ASCII差值
当差值大于0:目标字符串小(目标字符串就是传进来的参数)
当差值等于0:表示当前字符串=目标字符串
当差值小于0:目标字符串大
九.*字符串查找
从完整的字符串中判断指定内容是否存在
public boolean contains(String str):判断一个子字符串(连续的)是否存在
public int indexOf(String str):从头开始查找子字符串的位置,若找到返回索引,否则返回-1
public int lastIndexOf(String str):从后向前查找指定字符串,若找到返回索引,否则返回-1
public boolean startsWith(String prefix):判断是否以指定字符串开头
public boolean endsWith(String prefix):判断是否以指定字符串结尾
十.字符串替换
public String replaceAll(String regex,String replacement):将regex内容的字符串全部替换为replacement
public String replaceFirst(String regex,String replacement):替换regex中首个内容
十一.字符串拆分
将一个完整的字符串按照指定的格式拆分为若干个子字符串
public String split(String regex):将字符串全部拆分
若拆分结果显示为空,则指定字符串内容需要转义字符\
public String split(String regex,int limit):将字符串按照指定格式拆分为limit个子字符串
十二.字符串截取操作(规定:左闭右开)
public String substring(int beginIndex):从指定索引位置开始截取到字符串结尾
public String substring(int beginIndex,int endIndex):截取部分内容
这个方法有个很重要的应用就是处理首字母大写问题,演示下面代码:
这些只是本菜鸟理解的,欢迎大家补充!!