Java字符串String--StringBuffer--StringBuilder

String

String概念

String,字符串类,对多个字符的char[]类型进行封装,并实现了许多实用api接口

jdk9之后,Unicode的子集ASCII字符因为一个字节足以表示,所以此版本之后,ASCII字符会用字节数组byte[]存储,其他仍然使用char[]存储,以此优化String存储

String特点

  • 变量值不可变
  • 类不可被继承(被final修饰)

主要构造方法

String有很多构造方法在这里插入图片描述

  • String()
  • String(String)
  • String(byte[])
  • String(char[])
  • 字面量赋值法

字面量赋值,底层依靠常量池实现
当使用字面量创建字符串时,
JVM 首先会检查字符串常量池中是否已经存在相同内容的字符串。
如果已经存在,就直接返回该字符串在常量池中的引用;
如果不存在,则在常量池中创建一个新的字符串对象,并返回其引用

在文《java内存模型-static关键字》中,将常量池划分到方法区是不完全正确的
jdk7之前:常量池在方法区
jdk7及以后:常量池在堆内存

package tools;
public class TestString {
    public static void main(String[] args) {

        String s0 = new String();
        // 字面量赋值
        String s1 = "abc"; 
        // 传入String类型
        String s2 = new String(s1);
        // 传入字节数组
        byte[] bytes = {97,98,99};
        String s3 = new String(bytes);
        // 传入字符数组
        char[] chars = {'a','b','c'};
        String s4 = new String(chars);

        System.out.println("输出s0:"+s0);
        System.out.println("输出s1:"+s1);
        System.out.println("输出s2:"+s2);
        System.out.println("输出s3:"+s3);
        System.out.println("输出s4:"+s4);
    }
}

在这里插入图片描述

String值与内存

本质还是值与地址的问题

public class TestString {

    public static void main(String[] args) {

        String s0 = "abc";
        String s1 = "abc";

        String s2 = new String(s1);
        
        System.out.println(s1 == s0); // true ,共享了常量池的"abc"
        System.out.println(s2 == s1); // false,new之后,重新划分堆内存给s2,
        System.out.println(s2.equals(s1)); // true 值与s1一样,此张伟非彼张伟(String类的equals比较内容)
        
        String s3 = s1;
        System.out.println(s3 == s1); // true,共享了常量池的“abc”,大名张伟,小名阿伟

        s3 = s2;
        System.out.println(s3 == s2); // s2、s3的引用同样指向s2指向的地址,大名张伟,小名阿伟
        
        System.out.println(s1 + s2);  // abcabc 使用+号简单字符串拼接
    }
}

== 与 equals区别
==:逻辑远算符,比较基本类型的值或对象在堆的地址
equals:牢大Object类的一个方法,比较对象地址
在这里插入图片描述
String重写了此方法,判长、逐位比较
在这里插入图片描述

String类API接口

  • int lenght():返回字符串长度
  • char charAt(int index):返回index位置的字符,从0开始
  • boolean equals(Object object):主要比较String类的内容
  • boolean startsWith(String pref):判断是否以pref参数开头
  • boolean endsWith(String suf):判断是否以suf参数结尾
  • String substring(int begin):从指定的begin开始,截取到字符串末尾,返回一个新的字符串
  • String substring(int begin, int end):从指定的begin开始,截取到字符串end位置(不包括end位置),返回一个新的字符串
  • int indexof(int ch):返回ASCII数字sh对应的字符第一次出现的位置
  • int indexof(char ch):返回字符ch第一次出现的位置
  • int indexof(String s):返回字符串s第一次出现的位置
  • String replace(char old, char new):把所有的old字符替换成new的字符
  • String[] split(String regex):按照符合正则表达式的字符,分割字符串,得到字符串数组(不包括分割点)
  • String trim():去除字符串两头的孔字符串,返回新的字符串
package tools;

import java.util.Arrays;

public class TestString {

    public static void main(String[] args) {

        String s1 = "HelloWorld  !";
        System.out.println(s1.length());            // 13
        System.out.println(s1.charAt(1));           // e
        System.out.println(s1.equals("abcdefg"));   // false

        System.out.println(s1.startsWith("He"));    // true
        System.out.println(s1.endsWith("old"));     // false

        System.out.println(s1.substring(2));  // 截取:从2位置开始  lloWorld  !
        System.out.println(s1.substring(2,5));      // 截取:从2到5,不包括5   llo

        System.out.println(s1.indexOf(101));        // ASCII码101对应的字符出现的第一个位置  1
        System.out.println(s1.indexOf('e'));        // 字符'e'出现的第一个位置  1
        System.out.println(s1.indexOf("oW"));       // 字符串"oW"出现的第一个位置

        System.out.println(s1.replace('!','~'));       // 替换字符 HelloWorld  ~
        System.out.println(s1.replace("  !","~"));     // 替换字符串 HelloWorld~

        String s2 = " 12345  ";
        System.out.println(s2);
        System.out.println(s2.trim());  // 去除两端 "12345"

        String s3 = "java-C++-Python-Go";
        System.out.println(Arrays.toString(s3.split("-"))); 
        // 以'-'为分割点,分割字符串得到数组{"java","C++","Python","Go"}

    }
}

由上可知,当替换、截取等操作String对象,需要返回新的字符串,原来的String对象不改变

StringBuilder

可变字符串,需要关注
构造方法:StringBuilder(String s)
成员方法

  • StringBuilder append(String str):尾部拼接str,返回本身
  • StringBuilder insert(int index, String str):在index处插入字符串str(也可以传入char类型),返回本身
  • StringBuilder delete(int start, int end):删除start位置到end(不包括end位置),返回本身
  • StringBuilder deleteCharAt(int index):删去位置index的字符,返回本身
  • String toString():转成String类型
public class TestStringBuilder {
    public static void main(String[] args) {

        StringBuilder sb = new StringBuilder("97");
        System.out.println(sb);
        System.out.println(sb.append("9899100"));
        System.out.println(sb.insert(2,"101")); // 971019899100

        System.out.println(sb.delete(2,5));  // 删去101   979899100
        System.out.println(sb.deleteCharAt(5)); // 删去位置5的字符: 97989100
        System.out.println(sb.toString());   // 返回String类型的字符串,但不影响sb变量
        
    }
}

StringBuilder对象的操作都是返回自己,达到可变字符串的目的
在这里插入图片描述

StringBuffer

可变字符串
方法与StringBuilder相似,不同的是StringBuffer成员方法大多被synchronized关键字修饰使线程同步,达到可变字符串且线程安全的目的,正因如此,StringBuilder效率更快(无需处理线程同步)
StringBuffer更安全
在这里插入图片描述

String–StringBuffer–StringBuilder三者的关系总结
String 字符串不可变
StringBuffer成员方法被synchronized修饰,可变且线程安全
StringBuilder可变但线程不安全,但是因不需要处理线程同步,效率更快

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值