Java 中不可变字符串类是 String,属于 java.lang 包,它也是 Java 非常重要的类。
public class Main
{
public static void main(String[] args) {
//直接创建字符串常量
String s1="hello world";
System.out.println(s1);
//创建字符串对象
String s2=new String("hello world");
System.out.println(s2);
//通过字符数组创建字符串对象
char arr[]={'h','e','l','l','o'};
String s3=new String(arr);
System.out.println(s3);
String s4=new String(arr,1,3);//选取部分
System.out.println(s4);
//通过字节数组创建字符串对象
byte bytes[]={65,67,69};
String s5=new String(bytes);
System.out.println(s5);
}
}
hello world
hello world
hello
ell
ACE
Java 中的不可变字符串 String 常量,采用字符串池(String Pool)管理技术,字符串池是一种字符串驻留技术。采用字符串常量赋值时,会在字符串池中查找该字符串常量,如果已经存在把引用赋值给新变量,否则创建该字符串对象,并放到池中。
而使用new创建的字符串对象并不会放到字符串池
例子:
public class Main
{
public static void main(String[] args) {
//直接创建字符串常量
String s1="hello";
String s2="hello";
String s3=new String("hello");
String s4=new String("hello");
// %b代表boolean类型
System.out.printf("s1==s2:%b\n",s1==s2);//常量指向同一个引用
System.out.printf("s3==s4:%b\n",s3==s4);//对象是指向不同的引用
System.out.printf("s1==s3:%b\n",s1==s3);
}
}
s1==s2:true
s3==s4:false
s1==s3:false
public class Main
{
public static void main(String[] args) {
//直接创建字符串常量
String s1="hello world";
System.out.println(s1);
int len=s1.length();
System.out.println(len);
}
}
public class Main
{
public static void main(String[] args) {
//直接创建字符串常量
String s1="hello";
String s2=" world";
//使用+,可以连接任何类型
System.out.println(s1+s2);
//使用concat(),只能连接String类型,可以连续调用
System.out.println(s1.concat(s2));
}
}
在 String 类中提供了indexOf 和 lastIndexOf 方法用于查找字符或字符串,返回值是查找的字符或字符串所在的位置,-1 表示没有找到。这两个方法有多个重载版本:
从前往后搜索字符 ch,返回第一次找到字符 ch 所在处的索
引。
String s1="hello world";
int index=s1.indexOf('l');
System.out.println(index);
2
从指定的索引开始从前往后搜索字符 ch,返回第一次找到字符 ch 所在处的索引。
String s1="hello world";
int index=s1.indexOf('l',5);
System.out.println(index);
9
从前往后搜索字符串 str,返回第一次找到字符串所在处
的索引。
String s1="hello world";
int index=s1.indexOf("ll");
System.out.println(index);
2
同(2),也可以指定索引
从后往前搜索字符 ch,返回第一次找到字符 ch 所在处的
索引。
String s1="hello world";
int index=s1.lastIndexOf('l');
System.out.println(index);
9
子字符串也有类似的。
字符串本质上是字符数组,因此它也有索引,索引从零开始。
方法可以返回索引index所在位置的字符,常用来遍历字符串。
public class Main
{
public static void main(String[] args) {
String s1="hello";
String s2="HELLO";
boolean b1=s1.equals(s2);//直接比较
boolean b2=s1.equalsIgnoreCase(s2);//忽略大小写
System.out.println(b1+" "+b2);
}
}
按字典顺序比较两个字符串。如果参数字符串等于此字符串,则返回值 0;如果此字符串小于字符串参数,则返回一个小于0 的值;如果此字符串大于字符串参数,则返回一个大于 0 的值。
public class Main
{
public static void main(String[] args) {
String s1="hello";
String s2="HELLO";
int b1=s1.compareTo(s2);
int b2=s1.compareToIgnoreCase(s2);//忽略大小写
System.out.println(b1+" "+b2);
}
}
public class Main
{
public static void main(String[] args) {
String s1="hello";
String s2="HELLO";
boolean b1=s1.endsWith("lo");//字符串是否以指定的后缀结束
boolean b2=s2.startsWith("HE");//字符串是否以指定的前缀开始
System.out.println(b1+" "+b2);
}
}
public class Main
{
public static void main(String[] args) {
String s="hello world";
//从指定索引 beginIndex 开始截取一直到字符串结束的子字符串
String s1=s.substring(6);
System.out.println(s1);
//从指定索引 beginIndex 开始截取直到索引 endIndex - 1 处的字符,注意包括索引为 beginIndex 处的字符,但不包括索引为 endIndex 处的字符
String s2=s.substring(2,5);
System.out.println(s2);
//分割字符串得到字符串数组
String arr[]=s.split(" ");//可以指定以什么作为分隔符,这里是空格
for(int i=0;i<arr.length;i++)
{
System.out.println(arr[i]);
}
}
}
world
llo
hello
world
可变字符串在追加、删除、修改、插入和拼接等操作不会产生新的对象。
区别:
StringBuffer 和 StringBuilder 具有完全相同的 API,即构造方法和方法等内容一样。
public class Main
{
public static void main(String[] args) {
String s="hello world";
//默认构造
StringBuilder sb1=new StringBuilder();
int len1=sb1.length();
int cap1=sb1.capacity();
System.out.println(len1+" "+cap1);
//用String作为参数
StringBuilder sb2=new StringBuilder(s);
int len2=sb2.length();
int cap2=sb2.capacity();
System.out.println(sb2.toString());
System.out.println(len2+" "+cap2);
}
}
0 16
hello world
11 27
字符串长度和字符串缓冲区容量区别。字符串长度是指在字符串缓冲区中目前所包含字符串长度,通过length()获得;
字符串缓冲区容量是缓冲区中所能容纳的最大字符数,通过capacity()获得。当所容纳的字符超过这长度时,字符串缓冲区自动扩充容量,但这是以牺牲性能为代价的扩容。
字符串追加方法是 append,append 有很多重载方法,可以追加任何类型数据,它的返回值还是 StringBuilder。StringBuffer 的追加法与 StringBuffer完全一样。
public class Main
{
public static void main(String[] args) {
String s="hello";
StringBuilder sb=new StringBuilder(s);
sb.append(" ").append("world");
System.out.println(sb.toString());
sb.append(123).append(true);
System.out.println(sb);
}
}
hello world
hello world123true
StringBuilder insert(int offset, String str):在字符串缓冲区中索引为 offset 的字符位置之前插入 str,insert 有很多重载方法,可以插入任何类型数据。
public class Main
{
public static void main(String[] args) {
String s="helloworld";
StringBuilder sb=new StringBuilder(s);
sb.insert(5," ");
System.out.println(sb.toString());
}
}
hello world
StringBuffer delete(int start, int end):在字符串缓冲区中删除子字符串,要删除的子字符串从指定索引 start 开始直到索引 end - 1 处的字符。start 和 end 两个参数与 substring(int beginIndex, int endIndex)方法中的两个参数含义一样。
public class Main
{
public static void main(String[] args) {
String s="hello world";
StringBuilder sb=new StringBuilder(s);
sb.delete(5,s.length());
System.out.println(sb.toString());
}
}
hello
StringBuffer replace(int start, int end, String str)字符串缓冲区中用 str 替换子字符串,子字符串从指定索引 start 开始直到索引 end - 1 处的字符。start 和 end 同delete(int start, int end)方法。
public class Main
{
public static void main(String[] args) {
String s="hello world";
StringBuilder sb=new StringBuilder(s);
sb.replace(6,s.length(),"java");
System.out.println(sb.toString());
}
}
hello java