目录
1、简介
java中String不是基本数据类型,String中之所以能够保存字符串是因为其中定义了一个数组。
2、字符串的比较
public class StringDemo {
public static void main(String[] args) {
String strA= "abc";
String strB=new String("abc");
System.out.println(strA==strB);
}
}
结果:false
如上,字符串内容虽然相同,但是==的结果却是false,若是想要实现比较字符串内容的比较,需要用equals方法。
public class StringDemo {
public static void main(String[] args) {
String strA= "abc";
String strB=new String("abc");
System.out.println(strA.equals(strB));
}
}
结果:true
ps:这里介绍一个典型的面试题:
请解释String比较中“==”与equals()区别?
- == :进行的是数值比较,如果用于对象比较上比较的是两个内存的地址数值。
- equals() :是类所提供的一个比较方法,可以直接进行字符串内容比较。
3、String的实例化方式
1.直接赋值方式
public class StringDemo {
public static void main(String[] args) {
String strA = "abc";
String strB = "abc";
System.out.println(strA == strB);
}
}
结果:true
如上,==返回结果是true,因为Java底层专门提供了一个字符串常量池,在给strB赋值时,会首先去字符串常量池中查找是否有这个值,没有的话会在常量池中加入,有的话会直接将其地址给strB。
2.构造方法实例化
构造方法实例化,会构造两块堆内存空间,只使用一块,匿名对象开辟的内存空间会成为垃圾空间。
String strA = new String( "abc" );
构造方法实例化String对象不会自动保存到字符串常量池中。
所以以下执行的结果为false
public class StringDemo {
public static void main(String[] args) {
String strB=new String("abc");
String strA= "abc";
System.out.println(strA==strB);
}
}
但是构造方法有办法实现手动入池的操作,即intern方法,如下结果就是true,因为都引用的常量池里的"abc"
public class StringDemo {
public static void main(String[] args) {
String strB=new String("abc").intern();
String strA= "abc";
System.out.println(strA==strB);
}
}
ps:这里再介绍一个典型的面试题:
请解释String中两种对象实例化方法的区别?
- 直接赋值:只会产生一个实例化对象,并且可以自动保存到String对象(常量)池
- 构造方法:会产生两个实例化对象,并且不会自动入池,但是可以利用intern方法。
4、String对象(常量)池
对象池主要的目的是为了实现数据的共享,在Java中String对象池分为两种:
- 静态常量池:指的是程序在加载的时候会自动将此程序中保存的字符串、常量、类和方法等,全部进行分配;
- 运行时常量池:当一个程序加载之后,里面可能有一些变量,这个时候提供的常量池。
举例:
public class StringDemo {
public static void main(String[] args) {
String strA= "abc"+"123"+"DEF";
String strB="abc123DEF";
System.out.println(strA==strB);
}
}
结果:true
public class StringDemo {
public static void main(String[] args) {
String rr = "123";
String strA = "abc" + rr + "DEF";
String strB = "abc123DEF";
System.out.println(strA == strB);
}
}
结果:false
5、字符串修改
字符串不可修改
如上图,我们发现,这种处理下字符串常量的值并没有发生任何改变,只是开辟新的堆内存空间,并且改变strA的引用,这种改变会带来额外的垃圾空间。
若是我们在程序中频繁使用这种操作,会产生大量垃圾空间导致程序的性能非常差,所以在开发中尽量减少频繁更改String类内容的操作。
6、String类常用方法
- string(char[ ] value) 将传入的字符数组全变成字符串
public class StringDemo {
public static void main(String[] args) {
char[] cc = {'a', 'b', '1'};
System.out.println(new String(cc));
}
}
结果:ab1
- string(char[ ] value,int offset,int count) 将传入的字符数组部分变成字符串,offset是起始位置,count是范围大小
public class StringDemo {
public static void main(String[] args) {
char[] cc = {'a', 'b', '1','2','3'};
System.out.println(new String(cc,2,3));
}
}
结果:123
- charAt(int index) 获取指定索引位置的字符
public class StringDemo {
public static void main(String[] args) {
String str ="abcdefg";
System.out.println(str.charAt(2));
}
}
结果:c
- toCharArray() 将字符串中数据以字符数组的形式返回
public class StringDemo {
public static void main(String[] args) {
String str = "abcdefg";
char[] cc = str.toCharArray();
System.out.println(cc.length);
}
}
结果:7
- equals() 字符串判断,区分大小写
上文有介绍用法
- equalsIgnoreCase() 不区分大小写的判断
public class StringDemo {
public static void main(String[] args) {
String str = "abc";
String str1 = "ABC";
System.out.println(str.equalsIgnoreCase(str1));
}
}
结果:true
- compareTo() 字符串的比较,返回数字,ascii码值相减,区分大小写
public class StringDemo {
public static void main(String[] args) {
String str = "a";
String str1 = "A";
System.out.println(str.compareTo(str1));
}
}
结果:32
- compareToIgnoreCase()同上,不区分大小写
字节数组的String类应用
- string(byte[ ] value) 将传入的字节数组全变成字符串
- string(char[ ] value,int offset,int count) 将传入的字节数组部分变成字符串,offset是起始位置,count是范围大小
- string.getBytes() 将字符串转化为字节数组
- getBytes(String ccc) 编码转换
常用方法归类:
1.字符串查找
contains(String s) 判断子字符串是否存在
indexOf(String s)从头查找指定字符串的位置
intdexOf(String s, int fromIndex)从指定位置开始查找指定字符串的位置
public class StringDemo {
public static void main(String[] args) {
String str = "1234C";
System.out.println(str.indexOf("C",2));
}
}
结果:4
lastIndexOf(String str)从后往前找
lastIndexOf(String s, int fromIndex)从指定位置由后往前找
startsWith(String str)判断是否以指定字符串开头
public class StringDemo {
public static void main(String[] args) {
String str = "1234C";
System.out.println(str.startsWith("123"));
}
}
结果:true
startsWith(String str,int toffset)判断是否从指定位置以指定字符串开头
endsWith(String str)判断是否以指定字符串结尾
2.字符串替换
replaceAll(String regex,String replacement)全部替换
public static void main(String[] args) {
String str = "123V123";
System.out.println(str.replaceAll("123","abc"));
}
}
结果:abcVabc
replaceFirst(String regex,String replacement)替换首个
3.字符串拆分
split(String regex)按照指定字符串全部拆分
split(String regex,int limit)按照指定字符串限制拆分成指定段数
public class StringDemo {
public static void main(String[] args) {
String str = "123VV456VVaaVVcc";
for (String a : str.split("VV", 2)) {
System.out.println(a);
}
}
}
结果:
123
456VVaaVVcc
4.字符串截取
substring(int beginIndex)从指定位置开始截取到最后
substring(int beginIndex,int endIndex)设置了截取范围
public class StringDemo {
public static void main(String[] args) {
String str = "123VV456VVaaVVcc";
System.out.println(str.substring(3,8));
}
}
结果:VV456
5.字符串格式化
public class StringDemo {
public static void main(String[] args) {
String name = "KOBE";
int age = 18;
double high = 198.534;
String str = String.format("姓名:%s、年龄:%d,身高:%.2f", name, age, high);
System.out.println(str);
}
}
结果:
姓名:KOBE、年龄:18,身高:198.53
6.其他方法
concat()字符串连接
intern()字符串入池
isEmpty()字符串判断是否为""
length()返回字符串长度
trim()去除开头结尾的空格
toUpperCase()转大写
toLowerCase()转小写