String类:
    String直接赋值,会直接指向常量池,而不经过堆,并且常量池不会有重复的变量,但是如果涉及String类的计算,那么计算生成的对象就会指向堆,如下图:
    image.png

    image.png

    练习:

    1. package com.codeday25.demo03;
    2. public class StringTest {
    3. String str = new String("good");
    4. char[] ch = { 't', 'e', 's', 't' };
    5. public String change(String str, char ch[]) {
    6. str = "test ok";
    7. ch[0] = 'b';
    8. System.out.println("change方法里的str是" + str);
    9. System.out.println("change方法里的ch是" + new String(ch));
    10. return str;
    11. }
    12. public static void main(String[] args) {
    13. StringTest ex = new StringTest();
    14. String changeResult = ex.change(ex.str, ex.ch);
    15. System.out.print(ex.str + " and ");//
    16. System.out.println(ex.ch);
    17. System.out.println("change的结果是" + changeResult);
    18. }
    19. }

    image.png
    String类型的对象有不可变性,char类型的数组没有。并且str是作为形参进入change()方法的,这个方法并没有改变this中的str对象。应该是char类型的改变之后直接把栈里的一起改了,所以会变
    上面这个问题还要再理解。

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

    Stringbuffer
    String`StringBuffer\StringBuilder的异同<br />String:不可变的字符序列;底层用char[]数组存储<br />StringBuffer:可变的字符序列;线程安全的,效率偏低;底层用char[]数组存储<br />StringBuilder:可变的字符序列;线程不安全,效率高;底层用char[]`数组存储

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

    StringBuffer sb1 = new StringBuffer();// char[] value = new char[16];底层创建了一个长度是16的数组<br />System.out.println(sb1.length());// 0<br />sb1.append('a');// value[0] = 'a';<br />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,同时将原数组中的元素赋值到下新的数组中。

    开发中建议使用StringBufferStringBuffer(int)构造器。

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

    时间相关的类:(见PPT)

    字符串反转算法,我的和老师的:

    1. package com.codeday26.demo02;
    2. public class AlgoriTest {
    3. public static void main(String[] args) {
    4. String str = "fuckyou";
    5. String s = StringReverse.fanReverse(str,1,4);
    6. String t = StringReverse.songReverse(str,1,4);
    7. System.out.println(s + " fan");
    8. System.out.println(t + " song");
    9. }
    10. }
    11. class StringReverse{
    12. public static String fanReverse(String str,int startIndex,int endIndex){
    13. char[] charTemp = str.toCharArray();
    14. for (int i = startIndex-1; i < endIndex; i++) {
    15. charTemp[endIndex - i - 1] = str.charAt(i);
    16. }
    17. return new String(charTemp);
    18. }
    19. // 方式一
    20. public static String songReverse(String str, int startInex, int endIndex) {
    21. char[] arr = str.toCharArray();
    22. for(int x = startInex-1,y = endIndex-1;x < y;x ++,y --){
    23. char temp = arr[x];
    24. arr[x] = arr[y];
    25. arr[y] = temp;
    26. }
    27. return new String(arr);
    28. }
    29. // 方式二
    30. public static String Reverse2(String str, int startInex, int endIndex){
    31. String reverseStr = str.substring(0,startInex);
    32. for (int i = endIndex; i >= startInex; i--) {
    33. reverseStr += str.charAt(i);
    34. }
    35. reverseStr += str.substring(endIndex + 1);
    36. return reverseStr;
    37. }
    38. // 方式三
    39. public static String Reverse3(String str, int startInex, int endIndex){
    40. StringBuilder builder = new StringBuilder(str.length());
    41. // 第一部分
    42. builder.append(str.substring(0,startInex));
    43. // 第二部分
    44. for (int i = endIndex; i >= startInex; i--) {
    45. builder.append(str.charAt(i));
    46. }
    47. // 第三部分
    48. builder.append(str.substring(endIndex + 1));
    49. return builder.toString();
    50. }
    51. }

    获取一个字符串在另一个字符串中出现的次数。

    1. package com.codeday26.demo02;
    2. import org.junit.Test;
    3. import java.lang.module.FindException;
    4. import java.net.BindException;
    5. public class StringDemo1 {
    6. public static void main(String[] args) {
    7. int s = StringDetect.numOfCharAppoint("给我翻译翻译什么他妈的叫他妈的惊喜!", "他妈的");
    8. System.out.println(s);
    9. }
    10. @Test
    11. public void testGetCount(){
    12. String mainStr = "ababababab";
    13. String subStr = "aba";
    14. int count = getCount(mainStr,subStr);
    15. System.out.println(count);
    16. }
    17. public int getCount(String mainStr,String subStr){
    18. int mainLength = mainStr.length();
    19. int subLength = subStr.length();
    20. int count = 0;
    21. int index = 0;
    22. // 方式一
    23. // if(mainLength >= subLength){
    24. // while((index = mainStr.indexOf(subStr)) != -1){
    25. // count ++;
    26. // mainStr = mainStr.substring(index + 1);
    27. // }
    28. // }
    29. while((index = mainStr.indexOf(subStr,index)) != -1){
    30. count++;
    31. index += 1;
    32. }
    33. return count;
    34. }
    35. }
    36. class StringDetect {
    37. public static int numOfCharAppoint(String str, String targetStr) {
    38. if (str != null || targetStr != null || str.length() >= targetStr.length()) {
    39. int count = 0;
    40. int countTemp = 0;
    41. for (int i = 0; i < str.length(); i++) {
    42. if (i < str.length() - targetStr.length()) {
    43. for (int j = 0; j < targetStr.length(); j++) {
    44. if (str.charAt(i + j) == targetStr.charAt(j)) {
    45. countTemp += 1;
    46. }
    47. }
    48. }
    49. if (countTemp == targetStr.length()) {
    50. count += 1;
    51. }
    52. }
    53. return count;
    54. }else{
    55. return 0;
    56. }
    57. }
    58. }