目录
String类的两种实例化方式
1.直接赋值
String str = "Hello world!";
System.out.println(str);
2.通过构造方法实例化String对象
String str = new String("Hello world!");
System.out.println(str);
字符串相等比较
现在有两个int型变量,判断其相等可以用“==”完成。
int i = 10;
int j = 10;
System.out.println(i == j);//true
如果变量是String类型的,还可以用“==”来判断吗?
String str1 = "Hello";
String str2 = new String("Hello");
System.out.println(str1 == str2);//false
显然,这是不可以的。看看下面的内存图:
“==”本身是进行数值比较的,如果现在用于对象比较,那么比较的就是两个对象所保存的内存地址数值,并没有进行对象的内容的比较。
如果要进行内容的比较,就需要用到String类提供的equals方法。
String str1 = "Hello";
String str2 = new String("Hello");
System.out.println(str1.equals(str2));//true
字符串常量是String的匿名对象
之前出现的“String str = "Hello";”本质上就是将一个匿名的String类设置有名字,而且匿名对象一定保存在堆内存中。
String类的两种实例化区别
1.采用直接赋值
String str1 = "hello";
String str2 = "hello";
System.out.println(str1.equals(str2));//true
为什么没有开辟新的堆内存空间呢?
String类的设计使用了共享设计模式:
在JVM底层会自动维护一个字符串的对象池(对象数组),如果现在采用直接赋值的形式进行String的对象实例化,该对象(字符串内容)会自动保存在这个对象池中。如果下次继续使用直接赋值的模式声明String对象,此时对象池中若有内容,则直接引用;如果没有,则开辟新的堆空间后将其保存在对象池中供下次引用。
2.采用构造方法
String str = new String("hello");
分析:
通过分析可知,如果使用String构造方法就会开辟两块堆内存空间,并且其中一块堆内存会成为垃圾空间。除了这一缺点以外,也会对内存共享产生问题。
在String类中提供有方法入池操作public String intern();
String str1 = new String("hello").intern();//手工入池
String str2 = "hello";
System.out.println(str1 == str2);//true
字符串常量不可变更
字符串一旦定义不可改变。
观察下列代码:
public class Test1 {
public static void main(String[] args) {
String str = "hello";
str = str + "world";
System.out.println(str);
}
}
以上字符串的变更时字符串对象的变更,而非字符串常量。
可以发现字符串上没有任何变化,但对象的引用一直在改变,而且会形成大量的垃圾空间。
不建议用太多的“+=”。
原则:
字符串使用就采用直接赋值。
字符串比较就采用equals()实现。
字符串别改变太多。
字符与字符串
a.将数组转为字符串
public String(char[ ] value)
将数组中的内容转为字符串
public String(char[ ] value, int offset, int count)
将数组中的部分内容转为字符串
b.将字符串转为单个字符
public char charAt(int index);
c.将字符串变为字符数组
public char[ ] toCharArray( );
字节与字符串
a.将字节数组转为字符串
public String(byte[ ] value)
将字节数组转为字符串
public String(byte[ ] value, int offset, int count)
将字节数组部分转为字符串
b.将字符串转为字节数组
public byte[ ] getBytes( );
c. 将字符串按照指定编码转为字节数组
public byte[ ] getBytes(String charsetName);
字符串比较
a. 不区分大小写相等比较
public boolean equalsIgnoreCase(String anotherString)
b. 比较两个字符串大小
public int compareTo(String anotherString)
I. 返回大于0:表示大于比较对象
II. 返回等于0:两者相等
III. 返回小于0:表示小于比较对象
字符串查找
public boolean contains(String str):判断str在本字符串中是否存在
public boolean startsWith(String str):判断是否以指定字符串开头
public boolean startsWith(String str, int index):从指定位置开始判断是否以指定字符串开头
public boolean endsWith(String str):判断是否以指定字符串结尾
字符串替换
public String replaceAll(String regex, String replacement):替换所有指定内容
public String replaceFirst(String regex, String replacement):替换首个内容
字符串拆分
public String[ ] split(String regex):将字符串按照指定的格式全部拆分
public String[ ] split(String regex, int limit):将字符串全部拆分,数组长度为limit
字符串截取
public String substring(int beginIndex):从指定位置截取到字符串结尾
String str = "hello world";
String str1 = str.substring(6);
System.out.println(str1);//world
public String substring(int beginIndex, int endIndex):截取部分内容
String str = "hello world";
String str1 = str.substring(0,5);
System.out.println(str1);//hello
String类的其它方法
a. 去掉左右空格
public String trim( );
b. 转大小写
public String toUpperCase( );
public String toLowerCase( );
c. 判断字符串是否为空(只能判断是否为空字符串,而不是null)
public boolean isEmpty( );
StringBuffer类
由于String的不可更改性,为了方便字符串的修改,提供了StringBuffer类。
1.字符串修改
public StringBuffer append(各种数据类型);
StringBuffer str = new StringBuffer("hello");
str.append("HELLO");
System.out.println(str);//helloHELLO
2.字符串反转
public StringBuffer reverse( );
StringBuffer str = new StringBuffer("hello");
System.out.println(str.reverse());//olleh
3.删除指定范围的数据
public StringBuffer delete(int start, int end);
StringBuffer str = new StringBuffer("hello world");
System.out.println(str.delete(0,6));//world
4.插入数据
public StringBuffer insert(int offset, 各种数据类型);
StringBuffer str = new StringBuffer("hello world");
System.out.println(str.insert(11,"!!!"));//hello world!!!