一文带你深入理解【Java基础】· 常用类(上)字符串相关类

news2024/10/7 18:30:03

写在前面


        Hello大家好, 我是【麟-小白】,一位软件工程专业的学生,喜好计算机知识。希望大家能够一起学习进步呀!本人是一名在读大学生,专业水平有限,如发现错误不足之处,请多多指正!谢谢大家!!!

        如果小哥哥小姐姐们对我的文章感兴趣,请不要吝啬你们的小手,多多点赞加关注呀!❤❤❤ 爱你们!!!


目录

写在前面

1. String相关的类

1.1 String的特性

1.2 String对象的创建

1.3 String使用陷阱

1.4 String类代码演示

1.5 String常用方法

1.6 String与基本数据类型转换

 2. StringBuffer类

2.1 StringBuffer介绍

2.2 StringBuffer类的常用方法

3. StringBuilder类

3.1 StringBuilder和StringBuffer比较

结语


【往期回顾】

一文带你深入理解【Java基础】· 多线程(下)

一文带你深入理解【Java基础】· 多线程(上)

一文带你深入理解【Java基础】· 异常处理

一文带你深入理解【Java基础】· 面向对象编程(下)③接口和内部类

一文带你深入理解【Java基础】· 面向对象编程(下)②代码块、final和abstract

一文带你深入理解【Java基础】· 面向对象编程(下)①static和main方法


1. String相关的类


1.1 String的特性

  • String类:代表字符串。Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现。
  • String是一个final类,代表可变的字符序列
  • 字符串是常量,用双引号引起来表示。它们的值在创建之后不能更改。
  • String对象的字符内容是存储在一个字符数组value[]中的。
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

    /** Cache the hash code for the string */
    private int hash; // Default to 0


1.2 String对象的创建

String str = "hello";

//本质上this.value = new char[0];
String s1 = new String(); 

//this.value = original.value;
String s2 = new String(String original); 

//this.value = Arrays.copyOf(value, value.length);
String s3 = new String(char[] a); 
String s4 = new String(char[] a,int startIndex,int count);

 String str1 = “abc”;与String str2 = new String(“abc”);的区别?

  • 字符串常量存储在字符串常量池,目的是共享
  • 字符串非常量对象存储在堆中

结论:
  • 常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量。
  • 只要其中有一个是变量,结果就在堆中
  • 如果拼接的结果调用intern()方法,返回值就在常量池中

1.3 String使用陷阱

String s1 = "a";

  • 说明:在字符串常量池中创建了一个字面量为"a"的字符串。

s1 = s1 + "b";

  • 说明:实际上原来的“a”字符串对象已经丢弃了,现在在堆空间中产生了一个字符s1+"b"(也就是"ab")。如果多次执行这些改变串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。如果这样的操作放到循环中,会极大影响程序的性能。

String s2 = "ab";

  • 说明:直接在字符串常量池中创建一个字面量为"ab"的字符串。

String s3 = "a" + "b";

  • 说明:s3指向字符串常量池中已经创建的"ab"的字符串。

String s4 = s1.intern();

  • 说明:堆空间的s1对象在调用intern()之后,会将常量池中已经存在的"ab"字符串赋值给s4


1.4 String类代码演示

import org.junit.Test;
/**
 * String的使用
 */
public class StringTest {

    /*
    结论:
    1.常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量。
    2.只要其中有一个是变量,结果就在堆中。
    3.如果拼接的结果调用intern()方法,返回值就在常量池中
     */
    @Test
    public void test4() {
        String s1 = "javaEEhadoop";
        String s2 = "javaEE";
        String s3 = s2 + "hadoop";
        System.out.println(s1 == s3);//false

        final String s4 = "javaEE";//s4:常量
        String s5 = s4 + "hadoop";
        System.out.println(s1 == s5);//true
    }

    @Test
    public void test3() {
        String s1 = "javaEE";
        String s2 = "hadoop";

        String s3 = "javaEEhadoop";
        String s4 = "javaEE" + "hadoop";
        String s5 = s1 + "hadoop";
        String s6 = "javaEE" + s2;
        String s7 = s1 + s2;

        System.out.println(s3 == s4);//true
        System.out.println(s3 == s5);//false
        System.out.println(s3 == s6);//false
        System.out.println(s3 == s7);//false
        System.out.println(s5 == s6);//false
        System.out.println(s5 == s7);//false
        System.out.println(s6 == s7);//false

        String s8 = s6.intern();//返回值得到的s8使用的常量值中已经存在的“javaEEhadoop”
        System.out.println(s3 == s8);//true
    }

    /*
    String的实例化方式:
    方式一:通过字面量定义的方式
    方式二:通过new + 构造器的方式

     面试题:String s = new String("abc");方式创建对象,在内存中创建了几个对象?
            两个:一个是堆空间中new结构,另一个是char[]对应的常量池中的数据:"abc"
     */
    @Test
    public void test2() {
        //通过字面量定义的方式:此时的s1和s2的数据javaEE声明在方法区中的字符串常量池中。
        String s1 = "javaEE";
        String s2 = "javaEE";
        //通过new + 构造器的方式:此时的s3和s4保存的地址值,是数据在堆空间中开辟空间以后对应的地址值。
        String s3 = new String("javaEE");
        String s4 = new String("javaEE");

        System.out.println(s1 == s2);//true
        System.out.println(s1 == s3);//false
        System.out.println(s1 == s4);//false
        System.out.println(s3 == s4);//false

        System.out.println("***********************");
        Person p1 = new Person("Tom", 12);
        Person p2 = new Person("Tom", 12);

        System.out.println(p1.name.equals(p2.name));//true
        System.out.println(p1.name == p2.name);//true

        p1.name = "Jerry";
        System.out.println(p2.name);//Tom
    }

    /*
    String:字符串,使用一对""引起来表示。
    1.String声明为final的,不可被继承
    2.String实现了Serializable接口:表示字符串是支持序列化的。
            实现了Comparable接口:表示String可以比较大小
    3.String内部定义了final char[] value用于存储字符串数据
    4.String:代表不可变的字符序列。简称:不可变性。
        体现:1.当对字符串重新赋值时,需要重写指定内存区域赋值,不能使用原有的value进行赋值。
             2. 当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值。
             3. 当调用String的replace()方法修改指定字符或字符串时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值。
    5.通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串值声明在字符串常量池中。
    6.字符串常量池中是不会存储相同内容的字符串的。
     */
    @Test
    public void test1() {
        String s1 = "abc";//字面量的定义方式
        String s2 = "abc";
        s1 = "hello";

        System.out.println(s1 == s2);//比较s1和s2的地址值  false

        System.out.println(s1);//hello
        System.out.println(s2);//abc

        System.out.println("*****************");

        String s3 = "abc";
        s3 += "def";
        System.out.println(s3);//abcdef
        System.out.println(s2);//abc

        System.out.println("*****************");

        String s4 = "abc";
        String s5 = s4.replace('a', 'm');
        System.out.println(s4);//abc
        System.out.println(s5);//mbc
    }
}
import org.junit.Test;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;

/**
 * 涉及到String类与其他结构之间的转换
 */
public class StringTest1 {

    /*
    String 与 byte[]之间的转换
    编码:String --> byte[]:调用String的getBytes()
    解码:byte[] --> String:调用String的构造器

    编码:字符串 -->字节  (看得懂 --->看不懂的二进制数据)
    解码:编码的逆过程,字节 --> 字符串 (看不懂的二进制数据 ---> 看得懂)

    说明:解码时,要求解码使用的字符集必须与编码时使用的字符集一致,否则会出现乱码。
     */
    @Test
    public void test3() throws UnsupportedEncodingException {
        String str1 = "abc123中国";
        byte[] bytes = str1.getBytes();//使用默认的字符集,进行编码。
        System.out.println(Arrays.toString(bytes));//[97, 98, 99, 49, 50, 51, -28, -72, -83, -27, -101, -67]

        byte[] gbks = str1.getBytes("gbk");//使用gbk字符集进行编码。
        System.out.println(Arrays.toString(gbks));//[97, 98, 99, 49, 50, 51, -42, -48, -71, -6]

        System.out.println("******************");

        String str2 = new String(bytes);//使用默认的字符集,进行解码。
        System.out.println(str2);//abc123中国

        String str3 = new String(gbks);
        System.out.println(str3);//出现乱码。原因:编码集和解码集不一致!abc123�й�


        String str4 = new String(gbks, "gbk");
        System.out.println(str4);//没有出现乱码。原因:编码集和解码集一致!abc123中国
    }

    /*
    String 与 char[]之间的转换

    String --> char[]:调用String的toCharArray()
    char[] --> String:调用String的构造器
     */
    @Test
    public void test2() {
        String str1 = "abc123";  //题目: a21cb3

        char[] charArray = str1.toCharArray();
        for (int i = 0; i < charArray.length; i++) {
            System.out.println(charArray[i]);
        }

        char[] arr = new char[]{'h', 'e', 'l', 'l', 'o'};
        String str2 = new String(arr);
        System.out.println(str2);
    }

    /*
    复习:
    String 与基本数据类型、包装类之间的转换。

    String --> 基本数据类型、包装类:调用包装类的静态方法:parseXxx(str)
    基本数据类型、包装类 --> String:调用String重载的valueOf(xxx)

     */
    @Test
    public void test1() {
        String str1 = "123";
//        int num = (int)str1;//错误的
        int num = Integer.parseInt(str1);

        String str2 = String.valueOf(num);//"123"
        String str3 = num + "";

        System.out.println(str1 == str3);
    }
}

1.5 String常用方法

  • int length()返回字符串的长度: return value.length
  • char charAt(int index)返回某索引处的字符return value[index]
  • boolean isEmpty()判断是否是空字符串:return value.length == 0
  • String toLowerCase()使用默认语言环境,将 String 中的所有字符转换为小写
  • String toUpperCase()使用默认语言环境,将 String 中的所有字符转换为大写
  • String trim()返回字符串的副本,忽略前导空白和尾部空白
  • boolean equals(Object obj)比较字符串的内容是否相同
  • boolean equalsIgnoreCase(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 startsWith(String prefix)测试此字符串是否以指定的前缀开始
  • boolean startsWith(String prefix, int toffset)测试此字符串从指定索引开始的子字符串是否以指定前缀开始
  • boolean contains(CharSequence s)当且仅当此字符串包含指定的 char 值序列时,返回 true
  • int indexOf(String str)返回指定子字符串在此字符串中第一次出现处的索引
  • int indexOf(String str, int fromIndex)返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
  • int lastIndexOf(String str)返回指定子字符串在此字符串中最右边出现处的索引
  • int lastIndexOf(String str, int fromIndex)返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。注:indexOflastIndexOf方法如果未找到都是返回-1
  • 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个,如果超过了,剩下的全部都放到最后一个元素中。
import org.junit.Test;

public class StringMethodTest {

    /*
替换:
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个,如果超过了,剩下的全部都放到最后一个元素中。

     */
    @Test
    public void test4() {
        String str1 = "北京尚硅谷教育北京";
        String str2 = str1.replace('北', '东');

        System.out.println(str1);//北京尚硅谷教育北京
        System.out.println(str2);//东京尚硅谷教育东京

        String str3 = str1.replace("北京", "上海");
        System.out.println(str3);//上海尚硅谷教育上海

        System.out.println("*************************");
        String str = "12hello34world5java7891mysql456";
        //把字符串中的数字替换成,,如果结果中开头和结尾有,的话去掉
        String string = str.replaceAll("\\d+", ",").replaceAll("^,|,$", "");
        System.out.println(string);//hello,world,java,mysql

        System.out.println("*************************");
        str = "12345";
        //判断str字符串中是否全部有数字组成,即有1-n个数字组成
        boolean matches = str.matches("\\d+");
        System.out.println(matches);//true
        String tel = "0571-4534289";
        //判断这是否是一个杭州的固定电话
        boolean result = tel.matches("0571-\\d{7,8}");
        System.out.println(result);//true

        System.out.println("*************************");
        str = "hello|world|java";
        String[] strs = str.split("\\|");
        for (int i = 0; i < strs.length; i++) {
            System.out.println(strs[i]);
        }
        System.out.println();
        str2 = "hello.world.java";
        String[] strs2 = str2.split("\\.");
        for (int i = 0; i < strs2.length; i++) {
            System.out.println(strs2[i]);
        }
    }

    /*
boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束
boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始
boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始

boolean contains(CharSequence s):当且仅当此字符串包含指定的 char 值序列时,返回 true
int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引
int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引
int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索

注:indexOf和lastIndexOf方法如果未找到都是返回-1

     */
    @Test
    public void test3() {
        String str1 = "hellowworld";
        boolean b1 = str1.endsWith("rld");
        System.out.println(b1);//true

        boolean b2 = str1.startsWith("He");
        System.out.println(b2);//false

        boolean b3 = str1.startsWith("ll", 2);
        System.out.println(b3);//true

        String str2 = "wor";
        System.out.println(str1.contains(str2));//true

        System.out.println(str1.indexOf("lol"));//-1

        System.out.println(str1.indexOf("lo", 5));//-1

        String str3 = "hellorworld";

        System.out.println(str3.lastIndexOf("or"));//7
        System.out.println(str3.lastIndexOf("or", 6));//4

        //什么情况下,indexOf(str)和lastIndexOf(str)返回值相同?
        //情况一:存在唯一的一个str。情况二:不存在str
    }


    /*
int length():返回字符串的长度: return value.length
char charAt(int index): 返回某索引处的字符return value[index]
boolean isEmpty():判断是否是空字符串:return value.length == 0
String toLowerCase():使用默认语言环境,将 String 中的所有字符转换为小写
String toUpperCase():使用默认语言环境,将 String 中的所有字符转换为大写
String trim():返回字符串的副本,忽略前导空白和尾部空白
boolean equals(Object obj):比较字符串的内容是否相同
boolean equalsIgnoreCase(String anotherString):与equals方法类似,忽略大小写
String concat(String str):将指定字符串连接到此字符串的结尾。 等价于用“+”
int compareTo(String anotherString):比较两个字符串的大小
String substring(int beginIndex):返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个子字符串。
String substring(int beginIndex, int endIndex) :返回一个新字符串,它是此字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串。

     */
    @Test
    public void test2() {
        String s1 = "HelloWorld";
        String s2 = "helloworld";
        System.out.println(s1.equals(s2));//false
        System.out.println(s1.equalsIgnoreCase(s2));//true

        String s3 = "abc";
        String s4 = s3.concat("def");
        System.out.println(s4);//abcdef

        String s5 = "abc";
        String s6 = new String("abe");
        System.out.println(s5.compareTo(s6));//涉及到字符串排序 -2

        String s7 = "北京尚硅谷教育";
        String s8 = s7.substring(2);
        System.out.println(s7);//北京尚硅谷教育
        System.out.println(s8);//尚硅谷教育

        String s9 = s7.substring(2, 5);
        System.out.println(s9);//尚硅谷
    }

    @Test
    public void test1() {
        String s1 = "HelloWorld";
        System.out.println(s1.length());//10
        System.out.println(s1.charAt(0));//H
        System.out.println(s1.charAt(9));//d
//        System.out.println(s1.charAt(10));
//        s1 = "";
        System.out.println(s1.isEmpty());//false

        String s2 = s1.toLowerCase();
        System.out.println(s1);//s1不可变的,仍然为原来的字符串
        System.out.println(s2);//改成小写以后的字符串

        String s3 = "   he  llo   world   ";
        String s4 = s3.trim();
        System.out.println("-----" + s3 + "-----");//-----   he  llo   world   -----
        System.out.println("-----" + s4 + "-----");//-----he  llo   world-----
    }
}

/**
 * 一道面试题
 */
public class StringTest {
    String str = new String("good");
    char[] ch = {'t', 'e', 's', 't'};

    public void change(String str, char ch[]) {
        str = "test ok";
        ch[0] = 'b';
    }

    public static void main(String[] args) {
        StringTest ex = new StringTest();
        ex.change(ex.str, ex.ch);
        System.out.println(ex.str);//good String具有不可变性
        System.out.println(ex.ch);//best
    }
}


1.6 String与基本数据类型转换

字符串--> 基本数据类型、包装类
  • Integer包装类的public static int parse Int(String s):可以将由“数字”字符组成的字符串转换为整型。
  • 类似地,使用java.lang包中的ByteShortLongFloatDouble类调相应的类方法可以将由“数字”字符组成的字符串,转化为相应的基本数据类型。
基本数据类型、包装类--> 字符串
  • 调用String类的public String valueOf(int n)可将int型转换为字符串
  • 相应的valueOf(byte b)valueOf(long l)valueOf(float f)valueOf(doubled)valueOf(boolean b)可由参数的相应类型到字符串的转换
字符数组--> 字符串
  • String 类的构造器:String(char[]) String(char[]int offsetint length) 分别用字符数组中的全部字符和部分字符创建字符串对象。
字符串--> 字符数组
  • public char[] toCharArray()将字符串中的全部字符存放在一个字符数组中的方法。
  • public void getChars(int srcBegin, int srcEnd, char[] dst,int dstBegin)提供了将指定索引范围内的字符串存放到数组中的方法。
字节数组--> 字符串
  • String(byte[])通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String
  • String(byte[]int offsetint length) 用指定的字节数组的一部分,即从数组起始位置offset开始取length个字节构造一个字符串对象。
字符串--> 字节数组
  • public byte[] getBytes() 使用平台的默认字符集将此 String 编码为byte 序列,并将结果存储到一个新的 byte 数组中。
  • public byte[] getBytes(String charsetName) 使用指定的字符集将String 编码到 byte 序列,并将结果存储到新的 byte 数组。

 2. StringBuffer


2.1 StringBuffer介绍

  • java.lang.StringBuffer代表可变的字符序列JDK1.0中声明,可以对字符串内容进行增删,此时不会产生新的对象。
  • 很多方法与String相同。
  • 作为参数传递时,方法内部可以改变值。

StringBuffer 类不同于 String ,其对象必须使用构造器生成。有三个构造器:
  • StringBuffer():初始容量为16的字符串缓冲区
  • StringBuffer(int size):构造指定容量的字符串缓冲区
  • StringBuffer(String str):将内容初始化为指定字符串内容
String s = new String("我喜欢学习"); 
StringBuffer buffer = new StringBuffer("我喜欢学习"); 
buffer.append("数学");


2.2 StringBuffer类的常用方法

  • StringBuffer append(xxx):提供了很多的append()方法,用于进行字符串拼接
  • StringBuffer delete(int start,int end):删除指定位置的内容
  • StringBuffer replace(int start, int end, String str):把[start,end)位置替换为str
  • StringBuffer insert(int offset, xxx):在指定位置插入xxx
  • StringBuffer reverse() :把当前字符序列逆转
  • appendinsert时,如果原来value数组长度不够,可扩容。
  • 如上这些方法支持方法链操作。
  • 方法链的原理:
  • public int indexOf(String str)
  • public String substring(int start,int end)
  • public int length()
  • public char charAt(int n )
  • public void setCharAt(int n ,char ch)

3. StringBuilder


3.1 StringBuilder和StringBuffer比较

  • StringBuilder StringBuffer 非常类似,均代表可变的字符序列,而且提供相关功能的方法也一样

面试题:对比StringStringBufferStringBuilder

  • String(JDK1.0):不可变字符序列
  • StringBuffer(JDK1.0):可变字符序列、效率低、线程安全
  • StringBuilder(JDK 5.0):可变字符序列、效率高、线程不安全
  • 注意:作为参数传递的话,方法内部String不会改变其值,StringBufferStringBuilder会改变其值。
import org.junit.Test;

/**
 * 关于StringBuffer和StringBuilder的使用
 */
public class StringBufferBuilderTest {
    /*
    对比String、StringBuffer、StringBuilder三者的效率:
    从高到低排列:StringBuilder > StringBuffer > String
     */
    @Test
    public void test3() {
        //初始设置
        long startTime = 0L;
        long endTime = 0L;
        String text = "";
        StringBuffer buffer = new StringBuffer("");
        StringBuilder builder = new StringBuilder("");
        //开始对比
        startTime = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            buffer.append(String.valueOf(i));
        }
        endTime = System.currentTimeMillis();
        System.out.println("StringBuffer的执行时间:" + (endTime - startTime));//StringBuffer的执行时间:7

        startTime = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            builder.append(String.valueOf(i));
        }
        endTime = System.currentTimeMillis();
        System.out.println("StringBuilder的执行时间:" + (endTime - startTime));//StringBuilder的执行时间:2

        startTime = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            text = text + i;
        }
        endTime = System.currentTimeMillis();
        System.out.println("String的执行时间:" + (endTime - startTime));//String的执行时间:1247

    }

    /*
    StringBuffer的常用方法:
StringBuffer append(xxx):提供了很多的append()方法,用于进行字符串拼接
StringBuffer delete(int start,int end):删除指定位置的内容
StringBuffer replace(int start, int end, String str):把[start,end)位置替换为str
StringBuffer insert(int offset, xxx):在指定位置插入xxx
StringBuffer reverse() :把当前字符序列逆转
public int indexOf(String str)
public String substring(int start,int end):返回一个从start开始到end索引结束的左闭右开区间的子字符串
public int length()
public char charAt(int n )
public void setCharAt(int n ,char ch)

        总结:
        增:append(xxx)
        删:delete(int start,int end)
        改:setCharAt(int n ,char ch) / replace(int start, int end, String str)
        查:charAt(int n )
        插:insert(int offset, xxx)
        长度:length();
        *遍历:for() + charAt() / toString()
     */
    @Test
    public void test2() {
        StringBuffer s1 = new StringBuffer("abc");
        s1.append(1);
        s1.append('1');
        System.out.println(s1);//abc11
//        s1.delete(2,4);
//        s1.replace(2,4,"hello");
//        s1.insert(2,false);
//        s1.reverse();
        String s2 = s1.substring(1, 3);
        System.out.println(s1);//abc11
        System.out.println(s1.length());//5
        System.out.println(s2);//bc
    }

    /*
    String、StringBuffer、StringBuilder三者的异同?
    String:不可变的字符序列;底层使用char[]存储
    StringBuffer:可变的字符序列;线程安全的,效率低;底层使用char[]存储
    StringBuilder:可变的字符序列;jdk5.0新增的,线程不安全的,效率高;底层使用char[]存储

    源码分析:
    String str = new String();//char[] value = new char[0];
    String str1 = new String("abc");//char[] value = new char[]{'a','b','c'};

    StringBuffer sb1 = new StringBuffer();//char[] value = new char[16];底层创建了一个长度是16的数组。
    System.out.println(sb1.length());//
    sb1.append('a');//value[0] = 'a';
    sb1.append('b');//value[1] = 'b';

    StringBuffer sb2 = new StringBuffer("abc");//char[] value = new char["abc".length() + 16];

    //问题1. System.out.println(sb2.length());//3
    //问题2. 扩容问题:如果要添加的数据底层数组盛不下了,那就需要扩容底层的数组。
             默认情况下,扩容为原来容量的2倍 + 2,同时将原有数组中的元素复制到新的数组中。

            指导意义:开发中建议大家使用:StringBuffer(int capacity) 或 StringBuilder(int capacity)
     */
    @Test
    public void test1() {
        StringBuffer sb1 = new StringBuffer("abc");
        sb1.setCharAt(0, 'm');
        System.out.println(sb1);//mbc

        StringBuffer sb2 = new StringBuffer();
        System.out.println(sb2.length());//0
    }
}

结语


本人会持续更新文章的哦!希望大家一键三连,你们的鼓励就是作者不断更新的动力

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/19841.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[附源码]java毕业设计社区私家车位共享收费系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

基于51单片机的八路电压表采集Proteus仿真

资料编号&#xff1a;110 下面是相关功能视频演示&#xff1a; 110-基于51单片机的八路电压表采集Proteus仿真&#xff08;源码仿真原理图全套资料&#xff09;功能如下&#xff1a; 利用单片机及其外围器件&#xff08;A/D转换器等&#xff09;实现一款简易电压表&#xff0…

(免费分享)基于springboot医药进销存系统

源码获取&#xff1a;关注文末gongzhonghao&#xff0c;输入014领取下载链接 开发工具&#xff1a;IDEA,数据库mysql 技术&#xff1a;springbootmybatis 系统主要分两个角色&#xff0c;客户和员工 package cn.tedu.drug.controller;import java.io…

【Pytorch with fastai】第 18 章 :使用 CAM 进行 CNN 解释

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

Design a Facebook NewsFeed

title: Notes of System Design No.06 — Design a Facebook’s Newsfeed description: Design a Facebook’s Newsfeed ’ date: 2022-05-13 18:01:58 tags: 系统设计 categories: 系统设计 00. What is News Feed? 01.Functional Requirement 02. Non-Functional Requireme…

面试刷题---计算机网络部分(一)

1 请描述 TCP/IP 协议中主机与主机之间通信的三要素 答&#xff1a; IP 地址&#xff08;IP address&#xff09; 子网掩码&#xff08;subnet mask&#xff09; IP 路由&#xff08;IP router&#xff09; 扩展&#xff1a; TCP/IP定义&#xff1a;TCP/IP是基于TCP和IP这两个…

iHRM 人力资源管理系统_第11章_刷脸登录

iHRM 人力资源管理系统_第11章_刷脸登录 文章目录iHRM 人力资源管理系统_第11章_刷脸登录第11章 刷脸登录1 浅谈人工智能1.1 人工智能的概述1.2 人工智能的应用领域1.3 基于人工智能的刷脸登录介绍2 百度云AI概述2.1 概述2.2 百度云AI的开发步骤2.3 百度云AI的注册与认证3 百度…

web大作业 静态网页(地下城与勇士 10页 带视频)

⛵ 源码获取 文末联系 ✈ Web前端开发技术 描述 网页设计题材&#xff0c;DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 | 游戏官网 | 游戏网站 | 电竞游戏 | 游戏介绍 | 等网站的设计与制作 | HTML期末大学生网页设计作业&#xff0c;Web大学生网页 HTML&#xff1a;结构 …

开源免费的对象存储Minio

什么是Minio&#xff1f; Minio是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口&#xff0c;非常适合存储大容量、非结构化的数据。例如&#xff0c;图片、视频、日志文件、备份数据和容器/虚拟机镜像等&#xff0c;而一个对象文件可以是…

机器学习:卷积神经网络

卷积神经网络卷积神经网络的结构及原理卷积层池化层激活函数全连接层反馈运算使用MNIST数据集进行代码解析数据介绍实现流程代码实现卷积神经网络的结构及原理 卷积层 卷积运算一个重要的特点就是&#xff1a;通过卷积运算&#xff0c;可以使原信号特征增强&#xff0c;并且降…

服务器常用的异常及性能排查

服务器常用的异常及性能排查 使用 top 命令查看性能指标 top 命令使用详细介绍&#xff1a;传送门 查看Tasks total 进程数 正常我们在使用过程中对每天的一个进程数大概是有一个谱的&#xff0c;比如正常就是1百多个&#xff0c;突然暴增几百&#xff0c;那就很明显这里有…

计算机网络:运输层

运输层 运输层主要解决了应用进程之间的通信&#xff0c;称之为端到端协议 1.运输层概述 计算机网-------络体系结构的角度 AP:应用进程之间的简称 2. 运输层端口号、复用与分用的概念 2.1 端口号 2.2 发送方的复用&#xff08;multiplexing&#xff09;和接收方的分用&…

【Java面试八股文宝典之基础篇】备战2023 查缺补漏 你越早准备 越早成功!!!——Day10

大家好&#xff0c;我是陶然同学&#xff0c;软件工程大三明年实习。认识我的朋友们知道&#xff0c;我是科班出身&#xff0c;学的还行&#xff0c;但是对面试掌握不够&#xff0c;所以我将用这100多天更新Java面试题&#x1f643;&#x1f643;。 不敢苟同&#xff0c;相信大…

锐捷RLDP理论及实验讲解

RLDP概念 RLDP&#xff08;Rapid Link Detection Protocol&#xff09;是一个用于快速检测以太网链路故障的链路协议&#xff0c;包括环路链路故障、单向链路故障、双向链路故障等 工作原理 RLDP定义了两种协议报文&#xff1a;探测报文&#xff08;Probe&#xff09;和探测响…

【Java第32期】:Spring 中普通Maven项目的创建

作者&#xff1a;有只小猪飞走啦 博客地址&#xff1a;https://blog.csdn.net/m0_62262008?typeblog 内容&#xff1a;Spring 中普通Maven项目的创建 文章目录前言一&#xff0c;创建Spring项目1.创建一个普通的Maven项目2&#xff0c;添加Spring框架3&#xff0c;添加启动类…

【数据库系统概论】关系数据理论、范式

数据库一二三范式简单解释 第一范式 一个关系模式应当是一个五元组。 R(U,D,DOM,F)R(U,D,DOM,F)R(U,D,DOM,F) 这里&#xff1a; 关系名RRR是符号化的元组语义UUU为一组属性DDD为属性组UUU中的属性所来自的域DOMDOMDOM为属性到域的映射FFF为属性组UUU上的一组数据依赖 由于D…

RabbitMQ_概述

RabbitMQ大致工作流程图 解释 Producer&#xff1a;生产者 Consumer&#xff1a;消费者 Connection&#xff1a;AMQP协议连接 Channel&#xff1a;信道&#xff0c;进行消息读写的通道&#xff0c;RabbitMQ的绝大部分操作在信道完成&#xff1b;客户端可以建立多个信道&…

用 AWTK 和 AWPLC 快速开发嵌入式应用程序 (4)- 自定义功能块(上)

AWPLC 目前还处于开发阶段的早期&#xff0c;写这个系列文章的目的&#xff0c;除了用来验证目前所做的工作外&#xff0c;还希望得到大家的指点和反馈。如果您有任何疑问和建议&#xff0c;请在评论区留言。 1. 背景 AWTK 全称 Toolkit AnyWhere&#xff0c;是 ZLG 开发的开源…

PTA题目 两个数的简单计算器

本题要求编写一个简单计算器程序&#xff0c;可根据输入的运算符&#xff0c;对2个整数进行加、减、乘、除或求余运算。题目保证输入和输出均不超过整型范围。 输入格式&#xff1a; 输入在一行中依次输入操作数1、运算符、操作数2&#xff0c;其间以1个空格分隔。操作数的数…

跟艾文学编程《Python基础》(7)pandas数据分析

作者&#xff1a; 艾文&#xff0c;计算机硕士学位&#xff0c;企业内训讲师和金牌面试官&#xff0c;公司资深算法专家&#xff0c;现就职BAT一线大厂。邮箱&#xff1a; 1121025745qq.com博客&#xff1a;https://wenjie.blog.csdn.net/内容&#xff1a;跟艾文学编程《Python…