Java基础09 —— 字符序列--String、StringBuilder、StringBuffer区别及其方法介绍

Java基础09 —— 字符序列

字符串类型

字符与字符串

字符类型(char)是Java中的基本数据类型,占2个字节16位,默认值是 ‘\u0000’ 。字符是用单引号引住的单个符号.

// 字符
char c = 'A'; //单引号
char cA = 65; //数字
char c1 = '\u8888'; //Unicode码
System.out.println(c); //A
System.out.println(cA); //A
System.out.println(c1);//袈

字符串(String)是用双引号引住的任意个字符,是引用数据类型,默认值是null 。字符串其实就是字符组成的序列

字符串声明

String 变量名 = "初始值";
String 变量名 = new String("初始值");

举例:

String str = "张三"; // 字面量 比较常用
String str1 = new String("张三"); // 字符串对象

字符序列

多个字符按照一定的顺序组成的列表就叫作字符序列,字符串 java.lang.String 可以用来表示多个字符,用 “” 引

起来。

JDK13 新增文本块(预览),在 JDK15 正式在字符串支持文本块,用 “”" 表示

// Text Block 文本块声明
String season = """
				winter""";


//H i , LF(换行) SP(空格) " B o b " LF(换行)
String salutation = """
                    Hi,
                    "Bob"
                    """;
                        
// 输出为空
String empty = """
               """;

// 文本块 “”“ 字符内容 ”“”
   String text = """
                 序号    姓名
                 1      张三
                 "snadnlasmkl"
                 """;
   System.out.println(text);

String 字符串

StringBuffer 字符串缓冲区,是线程安全的

StringBuilder 字符串构造器,非线程安全的

CharBuffer 字符缓冲区

以上都实现了 CharSequence 接口

String类

字符串具有不可变特性;

public final static String是用final修饰的类,在java中用final修饰的类不能被继承,也就是说String没有子类。

java中,关键字final表示最终的。可以用来修饰类、方法、变量。

final修饰的类,不能被继承

final修饰的方法,不能被重写

final修饰的变量,不能变,如果是基本数据类型不能被重新赋值,如果是引用数据类型不能改变引用。

字符串不可变原因

字符串的底层是一个数组,jdk1.8之前是char类型的数组,jdk1.9及之后的版本是byte类型的数组。,不管是 jdk 8 及以前还是 jdk 9 及以后版本, value 属性都是 final 的。就说明,字符串一旦声明就不可变。所以字符串拥有不可变性。

改变原因:主要是为了节约 String 占用的内存,占用内存少引发另外一个好处就是减少 GC 次数。

**解释:**在java程序的堆里,String占用的空间最大,并且绝大多数String只有Latin-1字符,这些Latin-1字符只需要1字节就够了。在jdk9之前,jvm使用char类型的数组存储,char占用2个字节,即使字符串只需要1字节/字符,但依旧会按照2字节/字符进行存储,浪费了一半的内存空间。

jdk9的解决办法就是,一个字符串出来的时候判断,它是不是只有Latin-1字符,如果是,就按照1字节/每字符进行内存分配,如果不是就按照2字节/每字符规格进行分配(UTF-16编码),提高了内存使用率。

为什么用 UTF-16 而不用 UTF-8 呢

这就要从这两个字符集的设计说起了。UTF-8 实际上是对空间利用效率最高的编码集,它是不定长的,可以最大限度利用内存和网络。但是这种编码集只能用于传输和存储,并不适合拿来做 String 的底层实现。因为 String 有随机访问的方法,所谓随机访问,就是 charAtsubString 这种方法。如果字符串中的每个字符占用的内存是不定长的,那么进行随机访问的时候,就需要从头开始数每个字符的长度,才能找到你想要的字符。

使用 UTF-16 编码将它们表示并存储为每个字符2个字节。

对于 JDK9 和更高版本,默认情况下,如果 String 的行为已更改为对字符串使用紧凑表示形式。

String常用方法

1.构造方法

方法名 描述
String() 初始化新创建的 String对象,使其表示空字符序列
String(byte[] bytes) 通过使用平台的默认字符集解码指定的字节数组来构造新的 String
String(byte[] bytes, Charset charset) 构造一个新的String用指定的字节的数组解码charset
String(byte[] bytes, String charsetName) 构造一个新的String用指定的字节的数组解码charsetName
String(char[] value) 构造一个新的String由指定的字符的数组构成
String(String original) 初始化新创建的String对象,使其表示与参数相同的字符序列; 换句话说,新创建的字符串是参数字符串的副本
String(StringBuffer buffer) 分配一个新的字符串,其中包含当前包含在字符串缓冲区参数中的字符序列
String(StringBuilder builder) 分配一个新的字符串,其中包含当前包含在字符串构建器参数中的字符序列

2.实例方法

方法名 返回值 描述
charAt(int index) char 返回指定索引处的字符
codePointAt(int index) int 返回指定索引处的字符(Unicode代码点)。
compareTo(String anotherString) int 按字典顺序比较两个字符串
compareToIgnoreCase(String str) int 按字典顺序比较两个字符串,忽略大小写
concat(String str) String 将指定的字符串连接到该字符串的末尾
contains(CharSequence s) boolean 当且仅当此字符串包含指定的s值序列时才返回true
endsWith(String suffix) boolean 测试此字符串是否以指定的后缀结尾
startsWith(String prefix) boolean 测试此字符串是否以指定的前缀开头
equals(Object) boolean 比较字符串

常用方法进行分类: 查找字符的位置, 截取字符串, 拼接字符串等

字符串只能做+操作,表示拼接。任何类型的元素和字符串做+操作都表示字符串的拼接

contains()方法表示是否包含子元素,例如contains("wor")为true。

endsWith("内容")表示是否以某字符结尾,startsWith("内容")表示是否以某字符开头。

indexOf("字符")表示某个子串在字符串第一次出现的下标。-1表示未出现。

indexOf("字符",3)表示某个字符从索引位开始第一次出现的位置

intern如果字符串在常量池中有,就返回常量池中的对象,如果没有就将对象放入常量池中,并将这个对象返回。

自动装箱操作是通过包装类.valueOf()进行的,自动拆箱操作是通过包装类对象.xxxValue()进行的。

//占位符 %s 字符串 %bboolean %cchar %dinteger %f 浮点数

字符串判断相等:字符串(String)是引用数据类型,所以使用 equals 方法进行比较

// 字符串拼接 +
String str = "hello";
Str = str+" world";  //  hello world

//  分隔字符串 spilt()  用`-`做分隔符,然后通过`split()`方法转换成逗号并输出。
str = "1-2-3-4-5-6";
String[] strs = str.split("-");
System.out.println(Arrays.toString(strs));

//  重复
str = "666";
str = str.repeat(3);
System.out.println(str);

// 替换
str = "abcdabcd";
str = str.replace("a","A");// 会替换所有的a变成A
str = str.replaceFirst("a", "A");//只会替换第一次出现的a变成A
System.out.println(str);

// 格式化
str = "我是%s".formatted("张三");
System.out.println(str);   // 我是张三

// 判断是否包含
boolean contains = str.contains("hello world");
System.out.println(contains);

// 是否以某个字符串结尾
String email = "[email protected]";
boolean end = email.endsWith(".com");
System.out.println(end);

// 是否以某个字符串开头
boolean start = email.startsWith("xxx");
System.out.println(start);

// 子串在字符串中第一次出现的位置(下标), -1 表示没出现
int index = str.indexOf("e");
System.out.println(index);
int hello = str.indexOf("le");
System.out.println(hello); // -1

// 从 fromIndex开始第一次出现的下标
index = str.indexOf("l", 3);
System.out.println(index);

// 最后一次出现的位置
index = str.lastIndexOf("l");
System.out.println(index); // 9

// 分隔字符串
str = "1-2-3-4-5-6";
String[] strs = str.split("-");
System.out.println(Arrays.toString(strs));

// 合并 static方法
str = String.join(".", "a", "b", "c", "d");
System.out.println(str);


isEmpty 和 isBlank 区别

isEmpty 当且仅当字符串长度为0时返回 true

isBlank 当字符串长度为0或字符串中全是空白字符时都是 true

intern()用法

intern 如果字符串在常量池中有就返回常量池中的对象,如果没有就将对象放入常量池中,并将这个对象返回.

public class Demo07 {
	public static void main(String[] args) {
    /*
     intern 如果字符串在常量池中有就返回常量池中的对象,
            如果没有就将对象放入常量池中,并将这个对象返回
     */
        //        String str = "你好啊";
//
//
//        System.out.println(str);
//        System.out.println(System.identityHashCode(str));
//
//        String s = new String("你好啊").intern();
//
//        System.out.println(System.identityHashCode(s));
            // 1.
//        String str = "abc";
//
//        String s = new String("abc");
//
//        String s1 = s.intern();
//
//        System.out.println(str == s); // false
//        System.out.println(str == s1); // true
//        System.out.println(s == s1); // false  
        
             // 2.
//        String s = new String("abc");
//
//        String s1 = s.intern();
//
//        String str = "abc";
//
//        System.out.println(str == s); // false
//        System.out.println(str == s1); // true
//        System.out.println(s == s1); // false   
        
            // 3.
//        String  a = "a";
//        String s = new String(a + "bc");
//
//        String s1 = s.intern();
//
//        String str = "abc";
//
//        System.out.println(str == s); //  true
//        System.out.println(str == s1); // true
//        System.out.println(s == s1); //   true 
        
        // 4.
        String  a = "a";
        String s = new String(a + "bc");

        String str = "abc";

        String s1 = s.intern();
        System.out.println(str == s); //  false
        System.out.println(str == s1); // true
        System.out.println(s == s1); //   false

	}
}

valueOf() 类方法

有很多重载方法。涵盖了所有的数据类型转换 字符串的方法;

字符串 <—> 基本数据类型

public class Demo08 {
	public static void main(String[] args) {
    /*
           valueOf() 类方法,有很多重载方法。涵盖了所有的数据类型转换 字符串的方法;

           字符串 <---> 基本数据类型
     */
    // 任意类型转换为字符串
    byte b = 1;
    String str = String.valueOf(b);
    String.valueOf(true);
    String.valueOf(1.1);

    // int <---> String

    // 字符串 --> int  包装类.valueOf
    Integer a = Integer.valueOf("11");
    Integer.parseInt("11");
    System.out.println(a);
    // int  --> 字符串  String.valueOf()
    String s = String.valueOf(a);
	}
}

StringBuffer和StringBuilder

二者都是继承自抽象类AbstractStringBuilder

StringBuffer 中很多方法和 String 中的方法类似在此不再赘述

StringBuffer 是线程安全的类,StringBuilder是非线程安全的; String 不可变,所以是线程安全

StringBuilder执行效率相对较高.

StringBufferjdk1.0开始就提供了,而StringBuilderjdk1.5才提供的

两个类大部分实现都一样,不同点在于StringBuffer 中大部分方法都有 synchronized 修饰。synchronized 表示同步,修饰的方法表示同步方法。是多线程中一种线程安全的实现方法。

StringBuffer常用方法

方法名 返回值 描述
append(Object obj) StringBuffer 追加 Object参数的字符串
capacity() int 返回当前容量
trimToSize() void 尝试减少用于字符序列的存储空间
delete(int start,int end) StringBuffer 删除此序列的子字符串中的字符
reverse() StringBuffer 导致该字符序列被序列的相反代替
toString() String 返回表示此顺序中的数据的字符串
StringBuffer sb = new StringBuffer();
sb.append("a").append("b");

StringBuilder

一个可变的字符序列。 此类提供与 StringBuffer 相同的API,但不保证同步

在可能的情况下,建议使用 StringBuilder ,因为它在大多数实现中将更快

在使用 String 实例拼接(’ + ')时,编译器会使用 StringBuilder 来拼接字符串

class StringBuilderDemo {
        public static void main(String[] args) {

            // 16个长度的字符构建器
            StringBuilder sb = new StringBuilder();
            // 创建指定长度的 StringBuilder 对象
            sb = new StringBuilder(3);
            // 创建指定内容的 StringBuilder 对象
            //        sb = new StringBuilder("hello");
            System.out.println(sb.capacity());

            // 修改 StringBuilder 内容
            sb.append("a");
            sb.append("b");

            // 链式调用
            sb.append("c").append("d").append("e");

            // 删除某个位置
            //        sb.deleteCharAt(0);
            // 删除某个范围
//        sb.delete(0, 2);
            sb.insert(3, "A");

            // 数组长度 arr.length 字符串 str.length()
            //        System.out.println(sb.length());
            // StringBuilder --> String
            String str = sb.toString();
            System.out.println(str);
            System.out.println(sb.capacity());

            sb.reverse();
            System.out.println(sb.toString());
        }
    }

valueOf() 类方法

有很多重载方法。涵盖了所有的数据类型转换 字符串的方法;

字符串 <—> 基本数据类型

public class Demo08 {
	public static void main(String[] args) {
    /*
           valueOf() 类方法,有很多重载方法。涵盖了所有的数据类型转换 字符串的方法;

           字符串 <---> 基本数据类型
     */
    // 任意类型转换为字符串
    byte b = 1;
    String str = String.valueOf(b);
    String.valueOf(true);
    String.valueOf(1.1);

    // int <---> String

    // 字符串 --> int  包装类.valueOf
    Integer a = Integer.valueOf("11");
    Integer.parseInt("11");
    System.out.println(a);
    // int  --> 字符串  String.valueOf()
    String s = String.valueOf(a);
	}
}

包装类

public class Demo09 {
	public static void main(String[] args) {
    /*
        包装类
            自动装箱操作是通过 包装类.valueOf 进行的
            自动拆箱操作是通过 包装类对象.xxxValue() 进行
        包装类结构
     */

    Integer a = 1;
    int b = a;
// 	Integer n = Integer.valueOf(1);
//  Integer num = new Integer(1);
//  Integer num1 = new Integer("12");
    Integer num = 100;//  Integer.valueOf(100)
    Integer num1 = 100; // Integer.valueOf(100)

    System.out.println(num == num1);

    num = 200; // new Integer()
    num1 = 200; // new Integer();
    System.out.println(num == num1);

    // Byte  Short Character(0~127)  Integer Long 都有缓存对象数组
    Character c = '(';

    System.out.println(Character.isMirrored('['));
    }
}

你可能感兴趣的:(java,Java基础,java,开发语言)