Java-String及相关类

特点

  • 字符串是一个初始化的对象

  • 字符串一旦初始化就不可以被改变

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //创建一个字符串对象在常量池中
    //池中没有就建立,有就使用
    String str = "abc";
    String str1 = "abc";
    System.out.println(str == str1); //true

    //str2 是在堆内存中创建的一个String对象
    //创建两个对象一个new一个字符串对象在堆内存中
    String str2 = new String("abc");
    System.out.println(str == str2); //false
    System.out.println(str.equals(str2)); //true
    //String类中的equals方法复写了Object中的
    //其实就是比较字符串内容

构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
String str = new String();
//等价于 String str = "";
//不等价于 String str = null;

byte[] arr = {97,66,67,68};
String s1 = new String(arr);
System.out.println("s1 = "+s1);
//运行结果:s1 = aBCD

char[] chars = {'q','w','e','r','t'};
String s2 = new String(chars,1,3);
System.out.println("s2 = "+s2);
//运行结果:s2 = wer;

常见功能

获取

  • 获取字符串长度

    1
    int length();
  • 根据位置获取字符

    1
    char charAt(int index);
  • 根据字符获取在字符串中第一次出现的位置

    1
    2
    3
    4
    int indexOf(int ch);
    int indexOf(int ch,int fromIndex);//从指定位置查找
    int indexOf(String str);
    int indexOf(String str,int fromIndex);
  • 根据字符获取在字符串中最后一次出现的位置

    1
    2
    3
    4
    int lastIndexOf(int ch);
    int lastIndexOf(int ch,int fromIndex); //从指定位置反向搜索
    int lastIndexOf(String str);
    int lastIndexOf(String str,int fromIndex);
  • 获取字符串的一部分,也叫子串

    1
    2
    3
    注意:起始索引包括,结束索引不包括
    String substring(int beginIndex,int endIndex);
    String substring(int beginIndex);​

转换

  • 将字符串转换成字符串数组(字符串的切割)

    1
    String[] split(String regex);  涉及正则表达式
  • 将字符串转换成字符数组

    1
    char[] toCharArray();
  • 将字符串转换成字节数组

    1
    2
    byte[] getBytes();
    注意:一个汉字占两个字节,且这两个字节的最高位都是1
  • 将字符串的字母转成大小写

    1
    2
    String toUpperCase();  转大写
    String toLowerCase(); 转小写
  • 将字符串内容替换

    1
    2
    String replace(char oldch,char newch);
    String replace(String s1,String s2);
  • 将字符串两端空格去除

    1
    String trim();
  • 将字符串进行连接

    1
    String concat(String);

判断

  • 判断两个字符串内容是否相同

    1
    2
    3
    boolean equals(Object obj);
    忽略大小写比较内容:
    boolean equalsIgnoreCase(String str);
  • 字符串是否包含指定字符串

    1
    boolean contains(String str);
  • 字符串是否以指定字符串开头,或者结尾

    1
    2
    boolean startsWith(String);
    boolean endWith(String);

比较

  • 按字典顺序比较两个字符串

    1
    compareTo(String);

intern方法

  • 返回字符串对象的规范化表示形式

    1
    2
    String s1 = new String("abc");
    String s2 = s1.intern();

练习题

练习一

  • 1、计算一个子串在整串中出现的次数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    public class Basic_1 {
    public static void main(String[] args){
    String str = "nbaasdnbaanbanba";
    String key = "nba";
    //第一种方法会生成较多常量
    int count = getKeyStringCount(str,key);
    //第二种方法较好
    int count1 = getKeyStringCount_2(str,key );
    System.out.println(count);
    System.out.println(count1);
    }

    private static int getKeyStringCount_2(String str, String key) {
    int count = 0;
    int index = 0;
    //从index处开始判断是否还含有子串
    while((index = str.indexOf(key, index))!=-1){
    count++;
    //index加上刚才查找到的子串长度,从这里继续查
    index = index + key.length();
    }
    return count;
    }

    /**
    * 获取子串在整串中出现的个数
    * @param str
    * @param key
    * @return
    */
    private static int getKeyStringCount(String str, String key) {
    //定义计数器
    int count = 0;
    //记录变量key出现的位置
    int index = 0;
    //循环判断是否还含有子串,有则加1
    while((index = str.indexOf(key))!=-1) {
    //将字符串切割掉刚才查找过的位置
    str = str.substring(index+key.length());
    count ++;
    }
    return count;
    }
    }

练习二

  • 2、模拟一个与trim功能一致的方法(去除字符串两边空白)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public class Basic_4 {
    public static void main(String[] args){
    String str = " as s ";
    System.out.println(str);
    str = myTrim(str);
    System.out.println(str);
    }
    public static String myTrim(String str){
    int start = 0,end = str.length()-1;
    while (start<=end && str.charAt(start)==' '){
    start++;
    }
    while (start<=end && str.charAt(end)==' '){
    end--;
    }
    //注意:该方法结果包括起始索引,不包括结束索引
    str = str.substring(start, end+1);
    return str;
    }
    }

StringBuffer类

  • StringBuffer:就是字符串缓冲区,用于存储数据的容器
  • 可变数组原理:初始为16,超出后,长度翻倍至32,不够再增加

特点

  • 1、长度可变的
  • 2、可以存储不同类型数据
  • 3、最终要转成字符串使用
  • 4、可以对字符串修改

功能

  • 1、添加

    1
    2
    StringBuffer append(data);
    StringBuffer insert(index,data);
  • 2、删除

    1
    2
    StringBuffer delete(start,end);//删除头,不删除尾
    StringBuffer delete(index); //删除指定位置元素
  • 3、查找

    1
    2
    3
    char charAt(index);
    int indexOf(string);
    int lastOf(string);
  • 4、修改

    1
    2
    StringBuffer replace(start,end,string);
    void setCharAt(index,chars);

StringBuilder类

  • JDK1.5后出现了功能和StringBuffer一模一样的对象,就是StringBuilder
  • 不同的是:
    • StringBuffer 是线程同步的,建议多线程使用
    • StringBuilder是线程不同步的,建议单线程使用,提高效率
  • JDK升级:
    • 简化书写
    • 增加效率
    • 增加安全性

练习

  • 将一个 int 数组转字符串

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public static String arrayToString(int[] arr){
    StringBuilder sb = new StringBuilder();
    sb.append('[');
    for (int i = 0; i < arr.length; i++) {
    if(i!=arr.length-1)
    sb.append(arr[i]+',');
    else
    sb.append(arr[i]+']');
    }
    return sb.toString();
    }
  • 针对本题,使用String和StringBuilder的区别?

    • 使用String每次变化都会产生一个新的字符串常量池中的一个成员
    • 使用StringBuilder是不断的把字符串变成数组往容器里装