• Java字符串String、StringBuffer、StringBuilder的异同


    一、不可变字符串String

    Java 中不可变字符串类是 String,属于 java.lang 包,它也是 Java 非常重要的类。

    1、创建String

    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);
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    hello world
    hello world
    hello
    ell
    ACE
    
    • 1
    • 2
    • 3
    • 4
    • 5

    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);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    s1==s2:true
    s3==s4:false
    s1==s3:false
    
    • 1
    • 2
    • 3

    2、获取长度length()

    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);
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3、字符串拼接

    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));
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4、字符串查找

    在 String 类中提供了indexOf 和 lastIndexOf 方法用于查找字符或字符串,返回值是查找的字符或字符串所在的位置,-1 表示没有找到。这两个方法有多个重载版本:

    (1)int indexOf(int ch)

    从前往后搜索字符 ch,返回第一次找到字符 ch 所在处的索
    引。

    String s1="hello world";
    int index=s1.indexOf('l');
    System.out.println(index);
    
    2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    (2)int indexOf(int ch, int fromIndex)

    从指定的索引开始从前往后搜索字符 ch,返回第一次找到字符 ch 所在处的索引。

    String s1="hello world";
    int index=s1.indexOf('l',5);
    System.out.println(index);
    
    9
    
    • 1
    • 2
    • 3
    • 4
    • 5
    (3)int indexOf(String str)

    从前往后搜索字符串 str,返回第一次找到字符串所在处
    的索引。

    		String s1="hello world";
    		int index=s1.indexOf("ll");
    		System.out.println(index);
    
    2
    
    • 1
    • 2
    • 3
    • 4
    • 5

    同(2),也可以指定索引

    (4)int lastIndexOf(int ch)

    从后往前搜索字符 ch,返回第一次找到字符 ch 所在处的
    索引。

    		String s1="hello world";
    		int index=s1.lastIndexOf('l');
    		System.out.println(index);
    9
    
    • 1
    • 2
    • 3
    • 4

    子字符串也有类似的。

    (5)String的charAt(int index)

    字符串本质上是字符数组,因此它也有索引,索引从零开始。
    方法可以返回索引index所在位置的字符,常用来遍历字符串。

    5、字符串比较

    (1)比较相等equals
    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);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    (2)比较大小compareTo

    按字典顺序比较两个字符串。如果参数字符串等于此字符串,则返回值 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);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    (3)比较前缀和后缀
    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);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    6、截取字符串

    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]);
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    world
    llo
    hello
    world
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    二、可变字符串StringBuffer 和 StringBuilder

    可变字符串在追加、删除、修改、插入和拼接等操作不会产生新的对象。
    区别:

    • StringBuffer 是线程安全的,它的方法是支持线程同步,线程同步会操作串行顺序执行,在单线程环境下会影响效率。
    • StringBuilder 是 StringBuffer 单线程版本,Java 5 之后发
      布的,它不是线程安全的,但它的执行效率很高。

    StringBuffer 和 StringBuilder 具有完全相同的 API,即构造方法和方法等内容一样

    1、创建StringBuilder

    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);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    0 16
    hello world
    11 27
    
    
    • 1
    • 2
    • 3
    • 4

    字符串长度和字符串缓冲区容量区别。字符串长度是指在字符串缓冲区中目前所包含字符串长度,通过length()获得;
    字符串缓冲区容量是缓冲区中所能容纳的最大字符数,通过capacity()获得。当所容纳的字符超过这长度时,字符串缓冲区自动扩充容量,但这是以牺牲性能为代价的扩容。

    2、字符串追加append

    字符串追加方法是 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);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    hello world
    hello world123true
    
    
    • 1
    • 2
    • 3

    3、字符串插入、删除和替换

    (1)插入insert

    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());
    	    
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    hello world
    
    • 1
    (2)删除delete

    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());
    	    
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    hello
    
    
    • 1
    • 2
    (3)替换replace

    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());
    	    
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    hello java
    
    
    • 1
    • 2
  • 相关阅读:
    2022护网行动在即,关于护网的那些事儿
    软件开发项目文档系列之十二如何撰写用户培训方案
    ELK:开源搜索与分析技术栈(2)
    什么是序列化和反序列化?
    计算机毕业设计(附源码)python职业高中智慧教学系统
    项目经理,可别再用不好PEST分析法了
    Android笔记(二):JetPack Compose定义移动界面概述
    React Hooks —— ref hooks
    19、pixelNeRF
    简单函数模拟优化器
  • 原文地址:https://blog.csdn.net/qq_57987156/article/details/126256959