常用类之String类型
String类是用final修饰的,所以他不能被继承
在JDK1.8中,string内部使用char数组来储存数据的
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
private final char value[];
....
}
可以看出String实现了Serializable接口:表示字符串是支持可序列化的;Comparable:表示String是可比较大小的
通过字面量的方式(区别于new)给字符串赋值,此时的字符串值声明在字符串常量池中
String代表不可变的字符序列,简称:不可变性
- 当字符串被重新赋值时,需要重新指定内存区域赋值,不能使用原有的Value进行赋值
- 当字符串被拼接时,也需要重新指定内存区域赋值,不能使用原有的Value进行赋值
- 当使用字符串中的replace方法,修改字符串的指定字符时,也需要重新指定内存区域赋值,不能使用原有的Value进行赋值
通过代码来体现他的不可变性
package com.yellowstar.StringTest;
/**
* String的常用方法
*
* @Author YellowStar
* @Date 2021/7/2 13:31
*/
public class StringTest01 {
public static void main(String[] args) {
String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2); //true
s1 = "hello";
System.out.println(s1 == s2); //false
System.out.println(s1);
System.out.println(s2);
System.out.println("********************");
String s3 = "abc";
s3 += "def";
System.out.println(s2 == s3); //false
String s4 = "abc";
String s5 = s4.replace('a', 'm');
System.out.println(s4 == s5); //false
}
}
通过图片带你们感受一下String的内存原理
再来看一个例子
package com.yellowstar.StringTest;
/**
* @Author YellowStar
* @Date 2021/7/2 14:38
*/
public class StringTest02 {
public static void main(String[] args) {
String a = "javaEE";
String b = "Python";
String s1 = "javaEEPython";
String s2 = "javaEE" + "Python";
String s3 = a + "Python";
String s4 = "javaEE" + b;
String s5 = a + b;
String s6 = (a+b).intern();
System.out.println(s1 == s2);//true
System.out.println(s1 == s3);//false
System.out.println(s1 == s4);//false
System.out.println(s1 == s5);//false
System.out.println(s1 == s6);//true
System.out.println(s3 == s4);//false
}
}
- 常量与常量进行拼接结果会储存在常量池中且常量池不会有相同的对象
- 只要有一个是变量的拼接,拼接结果就会在堆中
- 拼接的时候调用String的intern方法,结果会储存在常量池中
一道非常经典的面试题
package com.yellowstar.StringTest;
/**
* 运行以下代码,输出结果为?
*
* @Author YellowStar
* @Date 2021/7/2 15:02
*/
public class StringTest03 {
public String str= new String("hello");
public char[] chars = {'t','e','s','t'};
public void change(String str,char[] chars){//这里传进来的str可以理解为复制了一份str,里面做的更改与外部没有关系
str = "world"; //这一行相当于 str = new String("world")
chars[0] = 'b';
}
public static void main(String[] args) {
StringTest03 stringTest03 = new StringTest03();
stringTest03.change(stringTest03.str,stringTest03.chars);
System.out.println(stringTest03.str);
System.out.println(stringTest03.chars);
}
}
结果:
hello
best
下面让我们来看一下String类型的常用方法
- int length():返回字符串的长度
- char charAt(int index):返回某索引处的字符
- boolean isEmpty():判断是否为空字符串
- String toLowerCase():使用默认语言环境,将String中的所有字符转换为小写
- String toUpperCase():使用默认语言环境,将String中的所有字符转换为大写
- String trim():返回字符串的副本,忽略开头结尾的空格
- boolean equals(Object obj):比较两个字符串的内容是否相同
- boolean equalsllgnoreCase(String anotherString):与equals方法相似,忽略大小写
- String concat(String str):将指定字符串连接到此字符串的结尾,相当于"+"
- int compareTo(String anotherString):比较两个字符串的大小,从第一位开始比较两个字符的大小
- String substring(int beginIndex):返回一个新的字符串,他是从此字符串的beginIndex开始截取到最后一个字符
- String substring(int beginIndex,int endIndex):返回一个新的字符串,他是此字符串beginIndex开始到endIndex(不包括)的一个字符串
- boolean endsWith(String suffix):测试此字符串是否以指定的字符串为后缀结束
- boolean stratsWith(String prefix):测试此字符串是否以指定的字符串为前缀开始
- boolean startsWith(String prifix,int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始
- boolean contains(CharSequence s):当且仅当此字符串包含指定的char值序列时,返回true
- int indexOf(String str):返回指定字符串在此字符串中第一次出现的位置,没出现则返回-1
- int indexOf(String str,int fromIndex):返回指定字符串在此字符串中第一次出现的位置,从指定的索引开始,没出现则返回-1,返回数值从0开始
- int lastIndexOf(String str):返回指定字符串在此字符串中最右边出现的索引
- int lastIndexOf(String str,int fromIndex):返回指定字符串在此字符串中最后一次出现的位置,从指定的索引开始反向搜索
- String replace(char oldChar,char newChar):返回一个新的字符串,他是通过用newChar替换此字符串中的所有oldChar得到的
- String replace(CharSequence target,CharSequence replacement):时用指定的字面值替换序列替换此字符串所有匹配字谜那只目标序列的子字符串
- String replaceAll(String regex,String replacement):使用给定的replacement替换此字符串中所有匹配给定的正则表达式的子字符串
- String replaceFirst(String regex,String replacement):使用给定的replacement替换此字符串中匹配给定的正则表达式的第一个子字符串
- boolean matches(String regex):告知此字符串是否匹配给定的正则表达式
- String[] split(String regex):根据给定正则表达式的匹配拆分此字符串
- String[] split(String regex,int limit):根据匹配给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下的全部放到最后一个元素中
String与基本数据类型的转换
- String转基本数据类型:调用包装类的静态方法 parseXxx()
- 基本数据类型转String:调用String的重载方法String.valueOf()
String与char数组之间的转换
- String转char[]数组:调用String的toCharArray
- char[]数组转String:直接调用String的构造方法即可
String与byte数组之间的转换
- String转byte数组:调用String的getbytes方法
- byte数组转String:直接调用String的构造方法
- 注意点:编码和解码的字符集要一致,否则会出现乱码的情况,默认是idea设置的字符集
package com.yellowstar.StringTest;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
/**
* @Author YellowStar
* @Date 2021/7/5 10:34
*/
public class StringText04 {
public static void main(String[] args) throws UnsupportedEncodingException {
String str1 = "abc123中国";
byte[] bytes = str1.getBytes();
System.out.println(Arrays.toString(bytes)); //我这里系统设置的是UTF-8
byte[] gbks = str1.getBytes("gbk");//这样可以设置使用gbk来进行编码
System.out.println(Arrays.toString(gbks));
System.out.println("***********************");
String str2 = new String(bytes);
System.out.println(str2);
String str3 = new String(gbks); //使用和编码不一样的字符集,会出现乱码的情况
System.out.println(str3);
String str4 = new String(gbks,"gbk");
System.out.println(str4);
}
}