Java commonly used classes String, StringBuffer, StringBuilder

Java common classes

1. String-related classes

1.1. The immutability of String

String: String, represented by a pair of "" quotes.

Strings are stored in char arrays at the bottom level.

  1. String is declared as finaland cannot be inherited

  2. String is implemented Serializable接口: indicating that the string supports serialization

    ​ Implemented Comparable接口: Indicates that String can be compared in size

  3. String internally defines final char[] value for storing string data

  4. String: Represents an immutable sequence of characters. Short name: Immutability.

    Reflection: 1. When reassigning a string, the assigned memory area needs to be rewritten, and the original value cannot be used for assignment. 2.
    When an existing string is connected, the memory area assignment also needs to be respecified. The original
    3. When calling the replace() method of String to modify the specified character or string, the memory area also needs to be re-specified.

  5. Assign a value to a string through literals (different from new). The string value at this time is declared in the string constant pool.

    String s1 = "abc";//字面量,不需要new,可以直接赋值
    
  6. Strings with the same content will not be stored in the string constant pool.

image.png

1.2. Comparison of different instantiation methods of String

String instantiation method:

  1. Method 1: Passing 字面量定义method
  2. Method 2: Passing new + 构造器method

Interview question: String s = new String("abc"); creates an object. How many objects are created in the memory?

Answer: Two. One is the new structure in the heap space, and the other is the data in the constant pool corresponding to char[]: "abc"

1.3. Comparison of different string splicing operations

  1. The result of concatenating constants and constants is in the constant pool. And there will be no constants with the same content in the constant pool.
  2. As long as one of them is a variable, the result is in the heap
  3. If the splicing result calls the intern() method, the return value will be in the constant pool.
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 = s7.intern();
    System.out.println(s3 == s8);//返回值得到的s8使用的常量池中已存在的"javaEEhadoop"
}

1.4. Common methods of String

***: Indicates very important

  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):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索
 注:indexOf和lastIndexOf方法如果未找到都是返回-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个,如果超过了,剩下的全部都放到最后一个元素中。

1.5. Conversion between String class and other structures

1.5.1. Conversion between String and basic data types and packaging classes

 		String s1 = "123";//在常量池中
//        int num = (int) s1;//错误
        int num = Integer.parseInt(s1);
        System.out.println(num);

        int n1 = 45689;
        String s2 = String.valueOf(n1);
        System.out.println(s2);//"123"
        String s3 = n1+"";//也可以,在堆空间中,只要有常量参与,都在堆空间中
        System.out.println(s3);
        System.out.println(s1 == s3);
        System.out.println(s1 == s3.intern());

1.5.2. Conversion between String and char[]

  • String —> char[]: Call String’s toCharArray()
String s1 = "abc123";
for (char c : s1.toCharArray()) {
    
    
	System.out.print(c);
	System.out.print('\t');
}
  • char[] —>String: Call the String constructor
char[] arr = new char[]{
    
    'h','e','l','l','o'};
String s2 = new String(arr);
System.out.println(s2);

1.5.3. Conversion between String and byte[]

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

 说明:解码时,要求解码使用的字符集必须与编码时使用的字符集一致,否则会出现乱码!
  • Encoding: String --> byte[]: Call String's getBytes()
//utf-8中一个汉字占3个字节
 String s1 = "abc123中国";//'1'相当于ASCI码中的49
 byte[] bytes = s1.getBytes();//使用默认的字符集,进行编码
 System.out.println(Arrays.toString(bytes));//[97, 98, 99, 49, 50, 51]
 
 //gbk字符集中一个汉字占2个字节
 byte[] gbks = s1.getBytes("gbk");//使用gbk字符集进行编码
 System.out.println(Arrays.toString(gbks));
  • Decoding: byte[] --> String: Call the String constructor
String s2 = new String(bytes);
System.out.println(s2);

//String s3 = new String(gbks);//出现乱码。原因:编码集和解码集不一致!
String s3 = new String(gbks, "gbk");
System.out.println(s3);

1.6. Common algorithm questions

1.6.1. Simulate a trim method to remove spaces at both ends of a string.



/**
 * @author: Arbicoral
 * @Description: 模拟一个trim方法,去除字符串两端的空格
 */
public class String1 {
    
    
    public static void main(String[] args) {
    
    
        String1 s1 = new String1();
        String s = "   abufs   dbf   fwf   ";
        System.out.println("原始字符串为:"+s);
        String res = s1.likeTrim(s);
        System.out.println();
        System.out.println("----------------");
        System.out.println("去除字符串两端的空格后的结果为:"+res);

    }

    public String likeTrim(String s){
    
    
        //1.转为char[]
        //2.通过 indexOf()挨个读取,是" "就去掉
        int n=s.length();//20
        char ch = ' ';
        char[] temp = s.toCharArray();
        int i=0;
        int j=n-1;
        while (true){
    
    
            if (temp[i] == ch){
    
    
                i++;
            }else
                break;
        }
        //走到这里,说明已经排除前面的空格了
//        System.out.println(i);//3
        while (true){
    
    
            if (temp[j] == ch){
    
    
                j--;
            }else
                break;
        }
//        System.out.println(j);//16
        //走到这里,说明已经排除后面的空格了

        char[] res = new char[j-i+1];
        int count = 0;
        for(int m=i; m<=j;m++){
    
    
            res[count] = temp[m];
            count++;
        }
        System.out.println(res.length);
        for (char c:res){
    
    
            System.out.print(c + "***");
        }

        //将res数组转为String
        String result = new String(res);
        return result;
    }
}

1.6.2. Reverse a string

Reverse the specified part of the string. For example, "abcdefg" is reversed to "abfedcg"



/**
 * @author: Arbicoral
 * @Description: 将字符串中指定部分进行反转。比如“abcdefg”反转为”abfedcg”  cdef-->fedc
 * 分析:
 * 需要两个指针
 *  ① 将s1变为char[],找到第 start_index 个元素,开始向后遍历 start_index+reverseLength个长度,用一个临时char交换下标的位置
 *  ② 将char[]恢复为字符串,并返回即可
 */
public class String2 {
    
    
    public static void main(String[] args) {
    
    
        String2 s = new String2();
        String s1 = "xssxcc";
        int start_index = 2;
        int reverseLength = 3;
        String res = s.reverseString(s1, start_index, reverseLength);//要给函数传 开始反转的下标和长度
        System.out.println("原始的字符串为:"+s1);
        System.out.println("从下标为" + start_index+ "开始,向后数反转"+ reverseLength +"个字符,得到反转后的字符串为:"+ res);
    }

    /**
     * 反转指定长度的函数
     * 方式一
     * @param start_index:开始反转的下标
     * @param reverseLength:反转的字符串的长度
     * @return
     */
    public String reverseString(String s1, int start_index, int reverseLength){
    
    
        char[] array = s1.toCharArray();
        int mid = reverseLength/2;//2
        char temp;
        int i = start_index;//开始反转的位置
        int j=start_index + reverseLength-1;//结束反转的位置
        while (i < (start_index+reverseLength-mid) && j >= start_index + reverseLength - mid){
    
    
            //start_index + reverseLength-1=5; start_index + reverseLength - mid=3
            //swap
            if (i==j){
    
    
                break;
            }else {
    
    
                temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
            //两个指针一个往前走,一个向后走
            i++;
            j--;
        }
        String res = new String(array);
        //恢复为String
        return res;
    }
}

    /**
     * 方式二:使用String进行拼接
     */
    public String reverseString2(String s1, int startIndex, int endIndex){
    
    
        if (s1 != ""){
    
    
            //第一部分
            String res = s1.substring(0,startIndex);
            //第二部分:倒着遍历
            for (int i=endIndex; i>=startIndex; i--){
    
    
                res += s1.charAt(i);
            }
            //第三部分
            res += s1.substring(endIndex+1);

            return res;
        }
        return null;
    }

    /**
     * 方式三:在方式二的基础之上,使用StringBuffer 或者StringBuilder替换String
     */
    public String reverseString3(String s1, int startIndex, int endIndex){
    
    
        if (s1 != ""){
    
    
            StringBuilder sb1 = new StringBuilder(s1.length());
            sb1.append(s1.substring(0,startIndex));
            for (int i=endIndex; i>=startIndex; i--){
    
    
                sb1.append(s1.charAt(i));
            }
            sb1.append(s1.substring(endIndex+1));
            return sb1.toString();
        }

        return null;
    }

1.6.3. Get the number of times a string appears in another string

For example: Get the number of times "ab" appears in "abkkcadkabkebfkabkskab"


/**
 * @author: Arbicoral
 * @Description: 获取一个字符串在另一个字符串中出现的次数
 */
public class String3cc {
    
    
    public static void main(String[] args) {
    
    
        String3cc s3 = new String3cc();
        String shortStr = "ab";
        String longStr = "abkkcadkabkebfkabkskab";
        int num = s3.countNum(shortStr, longStr);
        System.out.println(shortStr+"在"+longStr+"中出现的次数为:"+num);
    }

    public int countNum(String shortStr, String longStr){
    
    
        //
        int count = 0;
        int n = shortStr.length();//2
        int m = longStr.length();//22
        char[] ch1;
        ch1 = shortStr.toCharArray();
        char[] ch2 = longStr.toCharArray();
        boolean isAllEqual = false;//遍历完之后,是否全部一致
        int start_point_s=0; //记录ch1的起点,每一次外循环都需要归0;
        int start_point_l=0; //记录ch2的起点,不论本次循环是否找到都需要加1;
        // 外层循环
        while (start_point_l<=(m-n)){
    
    
            // 开启外循环
            int bianli_point_s=start_point_s; // 初始化ch1的遍历点
            int bianli_point_l=start_point_l; // 初始化ch2的遍历点
            // 内层循环
            while (bianli_point_s<=(n-1)){
    
    //x=0,1
                // 只要遇到不相等的字母,就结束内层循环,那么全部相等的情况下,bianli_point应该等于n
                if (!isEqual(ch1[bianli_point_s], ch2[bianli_point_l])){
    
    
                    break;
                }
                bianli_point_s++;
                bianli_point_l++;
            }
            // 如果ch1都参与了比较说明,全部相等
            if (bianli_point_s==n){
    
    
                isAllEqual=true;
            }
            //
            if (isAllEqual){
    
    
                //走到这里,说明 lastFlag=true,
                System.out.println("出现位置起点:"+start_point_l);
                count++;
            }
            // 参数重设定
            start_point_l++;
            start_point_s=0;
            isAllEqual=false;
        }
        return count;
    }

    /**
     * 用于判断两个字符是否相等
     * @param c1
     * @param c2
     * @return true; false
     */
    public boolean isEqual(char c1, char c2){
    
    
        if (c1 == c2){
    
    
            return true;
        }else
            return false;
    }
}


	/**
     * 方式二:使用String的常用方法:indexOf()
     */
    public int getNum(String shortStr, String longStr){
    
    
        int shortLen = shortStr.length();
        int longLen = longStr.length();
        int index = 0;
        int count = 0;
        if (longLen > shortLen){
    
    
            //
            while ((index = longStr.indexOf(shortStr, index)) != -1){
    
    
                count++;
                System.out.println("出现位置起点:"+ index);
                index += shortLen;
            }
            return count;
        }
        return 0;
    }

1.6.4. Get the largest identical substring in two strings

For example: str1 = "abcwerthelloyuiodef"; str2 = "cvhellobnm"

hint:

① Use dynamic programming to solve

② Start with the small ones and traverse the large strings in descending order.


/**
 * @author: Arbicoral
 * @Description: 获取两个字符串中最大相同子串
 *
 * 提示:使用动态规划解决
 */
public class String4 {
    
    
    public static void main(String[] args) {
    
    
        String4 s = new String4();
        String s1 = "abcwerthelloyuiodef";
        String s2 = "cvhellobnm";
//        String s1 = "abcwert";
//        String s2 = "cvlert";
        String maxSubstring = s.getMaxCommonSubstring(s1, s2);
        System.out.println("maxSubstring = " + maxSubstring);
    }

    /**
     * 方式一:获取两个字符串中最大相同子串
     */

    public String getMaxCommonSubstring(String s1, String s2){
    
    
        int m = s1.length();
        int n = s2.length();
        int maxLen = 0;//记录最大长度
        int endIndex = 0;//记录最长公共子串的终止位置
        int[][] arr = new int[m][n];
        for (int i=0;i<m; i++){
    
    //遍历s1
            for (int j=0;j<n;j++){
    
    //遍历s2
                if (s1.charAt(i) == s2.charAt(j)){
    
    
                    if (i == 0|| j==0){
    
    
                        arr[i][j] = 0;
                    }else {
    
    
                        arr[i][j] = arr[i - 1][j - 1] + 1;
                    }
                }else {
    
    
                    arr[i][j] = 0;
                }

                //获取最大长度
                if (arr[i][j] > maxLen){
    
    
                    maxLen = arr[i][j];
                    endIndex = i;
                }
            }
        }
        return s1.substring(endIndex-maxLen+1, endIndex+1);//前闭后开,所以 endIndex 要+1,不然取不到endIndex
    }
    
    
    
    
    /**
     * 获取两个字符串中最大相同子串:
     * 方法二:从小的开始,在大的字符串里依次递减进行遍历
     */
    public String getMaxSameString(String s1, String s2){
    
    
        if (s1.length() != 0 && s2.length() != 0){
    
    
            String maxStr = (s1.length() >= s2.length() ? s1 : s2);
            String minStr = (s1.length() < s2.length() ? s1 : s2);
            int length = minStr.length();
            for (int i=0; i<length; i++){
    
    //遍历最短的字符串
                for (int x=0,y=length-i; y<=length; x++,y++){
    
    
                    String subStr = minStr.substring(x,y);//子串
                    if (maxStr.contains(subStr)){
    
    
                        return subStr;
                    }
                }
            }
        }
        return null;
    }
}

1.6.5. Sort the characters in the string in natural order

hint:

1) The string becomes a character array.

2) Sort, select, bubble, Arrays.sort();

3) Convert the sorted array into a string.

import java.util.Arrays;

/**
 * @author: Arbicoral
 * @Description: 对字符串中字符进行自然顺序排序
 *
 * 提示:
 * 1)字符串变成字符数组。
 * 2)对数组排序,选择,冒泡,Arrays.sort();
 * 3)将排序后的数组变成字符串。
 */
public class String5 {
    
    
    public static void main(String[] args) {
    
    
        String5 s = new String5();
        String s1 = "zxcvbnm";
        System.out.println("排序前的字符串为:"+s1);
        String res = s.sort(s1);
        System.out.println("排序后的字符串为:"+res);
    }

    /**
     * 对字符串中字符进行自然顺序排序
     * @param s1:要排序的字符串
     * @return
     */
    public String sort(String s1){
    
    
        char[] array = s1.toCharArray();
        Arrays.sort(array);
        String res = new String(array);
        return res;
    }
}

二、StringBuffer、StringBuilder

Frequent interview questions: What are the similarities and differences between String, StringBuffer and StringBuilder?

Same point difference
String The bottom layer uses char[] storage immutable character sequence
StringBuffer The bottom layer uses char[] storage Mutable character sequences; thread-safe, inefficient
StringBuilder The bottom layer uses char[] storage Variable character sequence; new in jdk5.0, thread-unsafe and highly efficient

Compare the efficiency of String, StringBuffer and StringBuilder:

Arrange from high to low: StringBuilder > StringBuffer > String

2.1. StringBuffer source code analysis

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

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

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

//问题1:System.out.println(sb2.length())//3
//问题2:扩容问题:如果要添加的数据底层数组盛不下了,那就需要扩容底层的数组。
		//默认情况下,扩容为原来容量的2倍+2,同时将原有数组中的元素复制到新的数组中。
		
		//指导意义:开发中建议使用StringBuffer(int capacity) 或 StringBuilder(int capacity)

2.2. Common methods in StringBuffer and StringBuilder

* 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)
public int length()
public char charAt(int n )
public void setCharAt(int n ,char ch)

Focus:

增:append(xxx) //方法链的原理:一直append
删:delete(int start,int end)
改:setCharAt(int n ,char ch) / replace(int start, int end, String str)
查:charAt(int n )
插:insert(int offset, xxx):在指定位置插入xxx
长度:length()
遍历:for()+ charAt() / toString()

Guess you like

Origin blog.csdn.net/Miss_croal/article/details/132951000