目录
1.String类的两种实例化方式
-
直接赋值
-
传统方法(构造方法实例化)
代码示例:
/**
* String对象实例化
* Author:qqy
*/
public class Test {
public static void main(String[] args){
//直接赋值,在堆上分配空间
String str1="hello";
//通过构造方法实例化String对象
String str2= new String("aloha");
}
}
2.字符串相等比较
比较字符串内容,必须采用String类提供的equals方法。
public boolean equals(String anotherString)
- String类的 == 与 equals 的区别:
“==”是比较数值,在String类中比的是内存地址数值
equals比较的是字符串内容
代码示例:
/**
* 字符串比较
* Author:qqy
*/
public class Test1 {
public static void main(String[] args){
String str1="hello";
String str2=new String("hello");
//String是引用类型,str1和str2存放的是地址
//==比较值,str1==str2就是比较str1和str2的地址
System.out.println(str1==str2); //false
//equals方法比较字符串内容
System.out.println(str1.equals(str2)); //true
}
}
3.String的匿名对象
字符串常量("")是String的匿名对象
- 匿名对象一定保存在堆内存中
- 如果和String匿名对象进行比较,把字符串匿名对象放在前面,不会产生空指针异常——NullPointerException,因为匿名对象不可能为null。
public class Test2 {
public static void main(String[] args){
//假设str2由用户输入,若用户不输入
String str2 = null;
//"hello"是匿名对象
System.out.println("hello".equals(str2)); //false
//str2对象不存在
System.out.println(str2.equals("hello")); //可以编译,但存在空指针异常
}
}
4.实例化区别
-
4.1 直接赋值
若赋的值相等,则直接赋值并不会开辟新的堆内存空间
- 直接赋值法和构造法在内存空间分配的不同
public class Test14{
//总共开辟3个内存块
public static void main(String[] args){
//堆空间开辟1个内存块,共享(字符串共享池)
String str1 = "hello";
String str2 = "hello";
String str3 = "hello";
System.out.println(str1==str2); //true
System.out.println(str2==str3); //true
System.out.println(str1==str3); //true
String str4=new String("hello"); //堆空间上开辟2个内存块
System.out.println(str4==str1); //false
}
}
- 原因:
JVM底层会自动维护一个字符串的对象池(对象数组),若采用直接赋值的形式进行String的对象实例化,该对象会自动保存在该对象池中。如果下次继续使用直接赋值的模式声明String对象,此时对象池中若有指定内容,则直接使用;若没有,则开辟新的堆空间后将其保存在对象池中,供下次使用。
-
4.2 构造方法实例化
构造方法实例化会开辟两块堆内存空间,并且其中一块堆内存将成为垃圾空间。
- 手工入池:
public native String intern( ) ; 本地方法,没有方法体
代码示例:
/**
* 通过构造方法实例化的字符串对象入共享池
* Author:qqy
*/
public class Test3 {
public static void main(String[] args){
String str3=new String("hello").intern(); //入共享池
String str1 = "hello";
String str2=new String("hello");
System.out.println(str1==str2); //false
System.out.println(str1==str3); //true
}
}
以上述代码为例,str2中的"hello"会开辟一个空间,new String()也会开辟一个空间。当手工入池时,是将new String()入池,之后str1实例化时,会在共享池中寻找。
5.字符串常量不可变更
字符串一旦定义后不可改变,变更的只是引用,不是内容——如果对字符串的内容进行改变,就会开辟一个新的堆内存空间存放变更后的字符串内容,并非在原堆内存空间直接改变字符串内容。
代码示例:
public class Test14{
public static void main(String[] args){
String str1 = "hello"; //开辟一个堆内存空间
//world开辟一个,helloworld开辟一个,!开辟一个,helloworld!开辟一个
System.out.println(str1+"world"+"!");
}
}
6.字符与字符串的相互转换
-
6.1 字符数组 —> 字符串
//1.
public String(char[] value)
//2.
public String(char[] value,int offset,int count)
代码示例:
public class Test14{
public static void main(String[] args){
char[] ch = new char[]{'b','o','n','j','o','u','r','!'};
String str = new String(ch);
System.out.println(str); //bonjour!
//下标2开始,取5个
String str1 = new String(ch,2,5);
System.out.println(str1); //njour
}
}
-
6.2 字符串 —> 单个字符
//获取字符串指定索引位置的字符
public char charAt(int index);
代码示例:
public class Test14{
public static void main(String[] args){
char c = "bonjour".charAt(3);
System.out.println(c); //j
//c -> int类型 -> c+32
System.out.println(c+32); //138
}
}
-
6.3 字符串 —> 字符数组
public char[] toCharArray();
- 取得长度,数组是属性,字符串是方法
代码示例:
/**
* 字符串 -> 字符数组
* Author:qqy
*/
public class Test4 {
public static void main(String[] args){
char[] ch = "bonjour".toCharArray();
//length
//属性
System.out.println(ch.length); //7
//方法
System.out.println("bonjour".length()); //7
for(int i=0;i<ch.length;i++){
System.out.print(ch[i]-32);
if(i<ch.length-1) {
System.out.print(" "); //ASCII:66 79 78 74 79 85 82
}
}
}
}
- 练习:
/**
* 判断str的每个字符是否由0~9数字组成
* Author:qqy
*/
public class Test5 {
public static void main(String[] args) {
int i;
String str="123456h";
char[] ch=str.toCharArray();
for(i=0;i<str.length();i++){
if(ch[i]>=48 && ch[i]<=57){
continue;
}else {
System.out.println("false");
break;
}
}
if(i==str.length()) {
System.out.println("true");
}
}
}
7.字节与字符串的相互转换
-
7.1 字节数组 —> 字符串
//1.
public String(byte[] value)
//2.
public String(byte[] value,int offset,int count)
代码示例:
public class Test14{
public static void main(String[] args){
byte[] data = new byte[]{2,4,6,8};
String str = new String(data);
System.out.println(str);
String str1 = new String(data,2,2);
System.out.println(str1);
}
}
-
7.2 字符串 —> 字节数组
public byte[] getBytes();
代码示例:
/**
* 字符串 -> 字节数组
* Author:qqy
*/
public class Test6 {
public static void main(String[] args){
String str = "hello";
byte[] data = str.getBytes();
for(int i=0,j=data.length;i<j;i++){
System.out.println(data[i]); //104 101 108 108 111
}
}
}
-
7.3 字符串 —> 字节数组(按照指定编码)
public byte[] getBytes(String charsetName);
代码示例:
public class Test14{
public static void main(String[] args)throws Exception{
String str = "唱歌";
byte[] data = str.getBytes("gdk");
for(int i=0;i<data.length;i++){
System.out.println(data[i]);
}
System.out.println(new String(data));
}
}
8.字符串的比较
-
8.1 不区分大小写相等比较
public boolean equalsIgnoreCase(String anotherString);
-
8.2 区分大小写相等比较
public boolean equals(String anotherString);
代码示例:
public class Test14{
public static void main(String[] args){
System.out.println("hello".equalsIgnoreCase("Hello")); //true
System.out.println("hello".equals("Hello")); //false
}
}
-
8.3 比较两个字符串大小
public int compareTo(String anotherString)
a.返回大于0:表示大于比较对象
b.返回小于0:表示小于比较对象
c.返回等于0:两者相等
代码示例:
public class Test14{
public static void main(String[] args){
String str1 = "hello";
String str2 = "HEllo";
System.out.println(str1.compareTo(str2)); //32
System.out.println(str2.compareTo(str1)); //-32
System.out.println(str2.compareTo(str2)); //0
}
}
9.字符串查找
-
9.1 判断str在本字符串中是否存在
//String实现了CharSequence接口
//所以等同于contains(String str)
public boolean contains(CharSequence s)
代码示例:
public class Test14{
public static void main(String[] args){
String str1="hello world";
String str2="world";
System.out.println(str1.contains(str2)); //true
System.out.println(str2.contains(str1)); //false
}
}
-
9.2 判断是否以指定字符串开头
public boolean startsWith(String str)
-
9.3 判断是否以指定字符串开头(从指定位置开始)
public boolean startsWith(String str,int index)
代码示例:
public class Test14{
public static void main(String[] args){
String str1="hello world";
String str2="world";
String str3="hel";
System.out.println(str1.startsWith(str2)); //false
System.out.println(str1.startsWith(str3)); //true
System.out.println(str1.startsWith(str2,6)); //true
}
}
-
9.4 判断是否以指定字符串结尾(用法同9.2)
public boolean endsWith(String str)
-
9.5 从头开始查找指定字符串的位置
public int indexOf(String str)
- 如果内容重复,只返回查找的第一个位置
代码示例:
public class Test14{
public static void main(String[] args){
String str1="hello world";
String str2="l";
String str3="heli";
System.out.println(str1.indexOf(str2)); //2
System.out.println(str1.indexOf(str3)); //-1
}
}
10.字符串替换
//替换所有指定内容
public String replaceAll(String regex,String replacement)
//替换指定首个内容
public String replaceFirst(String regex,String replacement)
代码示例:
public class Test14{
public static void main(String[] args){
String str1="hello";
System.out.println(str1.replaceAll("l","2")); //he22o
System.out.println(str1.replaceFirst("l","3")); //he3lo
}
}
11.字符串拆分
//将字符串按照指定的格式全部拆分
public String[] split(String regex)
//将字符串部分拆分,数组长度为limit
public String[] split(String regex,int limit)
代码示例:
public class Test14{
public static void main(String[] args){
String str = "192.168.1.1";
String str1 = "C'est la vie !!!";
// .是引用,不能直接写".",应写成转义字符,但由于\也有特殊含义,因此写为\\.
String[] result = str.split("\\.");
String[] result1= str1.split(" ",2);
for(int i=0;i<result.length;i++){
System.out.print(result[i]+" ");
}
System.out.println();
System.out.println("------------------------------");
for(int i=0;i<result1.length;i++){
System.out.println(result1[i]);
}
}
}
运行结果:
12.字符串截取
//从指定位置截取到字符串结尾
public String substring(int beginIndex)
//截取部分内容
public String substring(int beginIndex,int endIndex)
代码示例:
public class Test14{
public static void main(String[] args){
String str = "C'est la vie";
//Java中遵循左闭右开原则,包含左边,不含右边
String result = str.substring(0,5);
String result1 = str.substring(6);
System.out.println(result); //C'est
System.out.println(result1); //la vie
}
}
13.其他操作方法
-
13.1 去掉左右空格
public String trim()
代码示例:
public class Test14{
public static void main(String[] args){
String str = " C'est la vie ";
System.out.println("["+str+"]"); //[ C'est la vie ]
System.out.println("["+str.trim()+"]"); //[C'est la vie]
}
}
-
13.2 转大小写
//转大写
public String toUpperCase()
//转小写
public String toLowerCase()
代码示例:
public class Test14{
public static void main(String[] args){
String str = " C'est la vie ";
System.out.println(str.toLowerCase()); // c'est la vie
System.out.println(str.toUpperCase()); // C'EST LA VIE
}
}
-
13.3 判断字符串是否为空
public boolean isEmpty()
- 只能判断是否为空字符串,而不是null
代码示例:
/**
* 字符串是否为空
* Author:qqy
*/
public class Test9 {
public static void main(String[] args){
String str = " C'est la vie ";
String str1 = "";
// System.out.println(null.isEmpty()); //空指针异常
System.out.println(str.isEmpty()); //flase
System.out.println(str1.isEmpty()); //true
//完整判断字符串是否为空
//str == null||str.isEmpty()
}
}
14.StringBuffer类
由于String不可更改的特性,为了方便字符串的修改,提供StringBuffer类
-
14.1 字符串连接
public StringBuffer append(各种数据类型)
代码示例:
public class Test14{
public static void main(String[] args){
StringBuffer str = new StringBuffer("C'est la vie");
//链式调用
str.append("!!! ").append("Bonjour");
System.out.println(str); //C'est la vie!!! Bonjour
}
}
- String和StringBuffer区别:
String的内容无法修改,而StringBuffer的内容可以修改。频繁修改字符串的情况考虑使用StingBuffer。
-
14.2 StringBuffer和String的相互转换
- 14.2.1 StringBuffer —> String
StringBuffer.toString();
- 14.2.2 String —> StringBuffer
调用StringBuffer的构造方法或append()
-
14.3 字符串反转
public StringBuffer reverse()
代码示例:
public class Test14{
public static void main(String[] args){
StringBuffer str = new StringBuffer("C'est la vie");
System.out.println(str.reverse()); //eiv al tse'C
}
}
-
14.4 删除指定范围的数据
public StringBuffer delete(int start, int end)
代码示例:
public class Test14{
public static void main(String[] args){
StringBuffer str = new StringBuffer("C'est la vie");
System.out.println(str.delete(0,5)); // la vie
}
}
-
14.5 插入数据
public synchronized StringBuffer insert(int offset, 各种数据类型)
代码示例:
public class Test14{
public static void main(String[] args){
StringBuffer str = new StringBuffer("C'est la vie");
System.out.println(str.insert(0,"Bonjour,")); //Bonjour,C'est la vie
}
}
- StringBuffer、StringBuilder的区别:
StringBuffer——同步处理,线程安全操作,效率较低
StringBuilder——异步处理,线程不安全操作,效率较高,String的 "+"操作,底层会将String —> StringBulider