字符串类

目录


String 类

String 概述

  • String 类在 java.lang 包下,所以使用的时候不需要导包。

  • String 类代表字符串,Java 程序中的所有字符串文字(例如"abc")都被实现为此类的实例。也就是说,Java 程序中所有的双引号字符串,都是 String 类的对象。

  • 字符串不可变,它们的值在创建后不能被更改。

  • String 这个类比较特殊,打印其对象名的时候,不会出现内存地址,而是该对象所记录的真实内容。


字符串的创建

String 类的创建有两种方式:一种是直接使用双引号赋值,另一种是使用 new 关键字创建对象。

1)直接创建:

String 字符串名 = "字符串内容";

2)使用 new 关键字创建:

String 类有多种重载的构造方法,具体如下:

  • String():创建一个空内容的字符串对象。
  • String(byte[] bytes):使用一个字节数组构建一个字符串对象。
  • String(byte[] bytes, int offset, int length):使用一个字节数组构建一个字符串对象。
    • offset:指定从数组中哪个索引值开始解码
    • length:要解码多少个元素
  • String(char[] value):使用一个字符数组构建一个字符串对象。
  • String(char[] value, int offset, int count):使用一个字符数组构建一个字符串对象,并指定开始的索引值与解码的个数。
  • String(int[] codePoints, int offset, int count):与字节数组一样
  • String(String original):用字符串构建字符串对象。
public class StringConstructor {

    public static void main(String[] args) {
        // public String():创建一个空白字符串对象,不含有任何内容
        String s1 = new String();
        System.out.println(s1);  // ""

        // public String(char[] chs):根据字符数组的内容,来创建字符串对象
        char[] chs = {'a', 'b', 'c'};
        String s2 = new String(chs);
        System.out.println(s2);  // "abc"

        // public String(String original):根据传入的字符串内容,来创建字符串对象
        String s3 = new String("123");
        System.out.println(s3);  // "123"
    }
}

创建字符串对象的区别对比:

  • 通过构造方法创建:通过 new 创建的字符串对象,每一次 new 都会申请一个内存空间,虽然内容相同,但是地址值不同。

  • 直接赋值方式创建:以 "" 方式给出的字符串,只要字符序列相同(顺序和大小写),无论在程序代码中出现几次,JVM 都只会建立一个 String 对象,并在字符串池中维护。

字符串的比较:

  • ==:比较基本数据类型时,比较的是具体的值;比较引用数据类型时,比较的是对象地址。
  • String 类的 public boolean equals(String s):比较两个字符串内容是否相同、区分大小写。

字符串类

public static void test(String str){
     // 技巧:str 有可能指向空(null)对象,放前面的话可能会出现空指针异常。
     // 因此常将常量放前面作为 equals 的调用者,杜绝空指针异常。
     if("中国".equals(str)){  
          System.out.println("回答正确");     
     }else{
          System.out.println("回答错误");
     }
}

String 常用方法

获取方法 说明
int length() 获取字符串的长度
char charAt(int index) 返回指定索引处的 char 值
int indexOf(String str) 查找子串第一次出现的索引值。若子串不存在,则返回 -1
indexOf(String str, int fromIndex) 从指定的索引值开始查找子串
int lastIndexOf(String str) 返回指定子字符串在此字符串中最右边出现处的索引,如果此字符串中没有这样的字符,则返回 -1
int lastIndexOf(String str, int fromIndex) 返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索,如果此字符串中没有这样的字符,则返回 -1
String concat(String str) 实现将一个字符串(参数 str)连接到另一个字符串后面
判断方法 说明
boolean startsWith(String str) 是否以指定字符开头
boolean endsWith(String str) 是否以指定字符结束
boolean isEmpty() 是否长度为 0
boolean contains(charSequences) 是否包含子串。
多态:charSequences 参数属于接口,String 是它的实现类
boolean equals(Object anObject) 判断两个字符串的内容是否一致
boolean equalsIgnoreCase(String anotherString) 忽略大小写,判断两个字符串的内容是否一致
boolean matches(String regex) 进行正则表达式的验证,若匹配则返回 true。
操作方法 说明
String replace(CharSequence target, CharSequence replacement) 将字符串中的旧值替换成新值,得到新的字符串
String[] split(String regex) 根据指定的字符进行切割
String substring(int beginIndex) 从传入的索引处截取,截取到末尾,得到新的字符串
public String substring(int beginIndex, int endIndex) 根据开始和结束索引进行截取,得到新的字符串(包头不包尾)
String toUpperCase() 转大写
String toLowerCase() 转小写
String trim() 去掉字符串前后的空格字符
数组转换方法 说明
Char[] toCharArray() 将字符串转换为字符数组
Byte[] getBytes() 将字符串转换为字节数组

示例:

    public static void main(String[] args) {
        // 字符串转数组
        byte[] a = "abc".getBytes();
        char[] b = "abc".toCharArray();
        System.out.println(a);  // [B@1b6d3586
        System.out.println(b);  // abc

        // 数组的字符串表示形式
        System.out.println(Arrays.toString(a));  // [97, 98, 99]
        System.out.println(Arrays.toString(b));  // [a, b, c]

        /* 数组转字符串 */
        StringBuffer stringBuffer = new StringBuffer();
        for (char s : b) {
            stringBuffer.append(s + "");
        }
        System.out.println(stringBuffer);
        
    }

字符串的类型转换

数据类型 字符串转换为其他数据类型的方法 其他数据类型转换为字符串的方法1 其他数据类型转换为字符串的方法2
byte Byte.parseByte(str) String.valueOf(byte bt) Byte.toString(byte bt)
int Integer.parseInt(str) String.valueOf(int i) Int.toString(int i)
long Long.parseLong(str) String.valueOf(long l) Long.toSting(long l)
double double.parseDouble(str) String.valueOf(double d) Double.toString(double b)
float Float.parseFloat(str) String.valueOf(float f) Float.toString(float f)
char str.charAt(int index) String.valueOf(char c) Character.toString(char c)
boolean Boolean.getBoolean(str) String.valueOf(boolean b) Boolean.toString (boolean b)

String 类不可变的好处

  1. 不可变对象可以提高 String Pool(字符串常量池)的效率。如果知道一个对象是不可变的,那么需要复制对象的内容时不用复制它本身而只是复制它的地址,复制地址(通常一个指针的大小)只需要很小的内存,效率也很好。并且对其他引用同一个对象的变量也不会造成影响。

  2. 因为字符串时不可变的,所以是多线程安全的,同一个字符串实例可以被多个线程共享。这样便不用因为线程安全问题而使用同步。

  3. 因为字符串是不可变的,所以在创建它的时候哈希码就被缓存了,不需要重新计算。这就使得字符串很适合作为 Map 中的键,字符串的处理速度要快过其他键对象。这就是 HashMap 中的键往往都使用字符串的原因。

格式化字符串的方法

String 类的 format() 方法使用指定的格式字符串和参数,返回一个格式化字符串。

常规类型格式化的语法格式:format(String format, Object…args)

  • format:格式字符串。
  • args:格式字符串中由格式说明符引用的参数。参数数目是可变的,可以为 0。
转换符 说 明 示例
%b、%B 格式化为布尔类型 false
%h、%H 格式化为哈希码 A05A5198
%s、%S 格式化为字符串类型 "abc"
%c、%C 格式化为字符类型 'w'
%d 格式化为十进制数 26
%0 格式化为八进制数 12
%x、%X 格式化为十六进制数 4b1
%e 格式化为用计算机科学计数法表示 的十进制数 1.700000e+01
%a 格式化为带有效位数和指数的十六 进制浮点值 0X1.C000000000001P4

示例:

String s1 = String.format("%d", 400/2);  // 200
String s2 = String.format("%b", 3>5);  // false

常规类型的格式化可应用于任何参数类型,转换符如下:

日期时间格式化的语法格式:format(Locale, String format, Object…args)

  • Locale:格式化过程中要应用的语言环境。如果为空则不进行本地化。
  • format:格式字符串。
  • args:格式字符串中由格式说明符引用的参数。如果还有格式说明符以外的参数,则忽略这些额外的参数。参数的数目是可变的,可以为 0。

下表为 format() 方法常用的日期和时间转换符:

转换符 说明 示例
%te 一个月中的某一天(1~31) 12
%tb 指定语言环境的月份简称 Jan(英文)、一月(中文)
%tB 指定语言环境的月份全称 February(英文)、二月(中文)
%tA 指定语言环境的星期几全称 Monday(英文)、星期一(中文)
%ta 指定语言环境的星期几简称 Mon(英文)、星期一(中文)
%tc 包括全部日期和时间信息 星期三十月 25 13:37:22 CST 2008
%tY 4 位年份 2008
%tj 一年中的第几天(001~366) 060
%tm 月份 05
%td 一个月中的第几天(01~31) 07
%ty 两位年份 08

示例:

Date date = new Date();
Locale form = Locale.US;
String year = String.format(form, "%tY", date);
String month = String.format(form, "%tB", date);
String day = String.format(form, "%td", date);
System.out.println("当前年份:"+year);  // 当前年份:2021
System.out.println("当前月份:"+month);  // 当前月份:November
System.out.println("当前日份:"+day);  // 当前日份:06

StringBuffer 类

StringBuffer 概述

字符串特点:

  1. 字符串是常量,它们的值在创建之后不能更改。
  2. 字符串的内容一旦发生了变化,那么马上会创建一个新的对象。

因此,字符串的内容不适宜频繁修改,因为一旦修改马上就会创建一个新的对象。如果需要修改字符串的内容,建议使用字符串缓冲类——StringBuffer:一个存储字符的容器

StringBuffer 底层是依赖一个字符数组才能存储字符数据的,该字符数组默认的初始容量是 16,如果字符数组的长度不够用,自动增长一倍(再加 2)。

StringBuffer 常用方法

增:

方法名 说明
StringBuffer append(String/boolean/ ...) 可以添加任意类型的数据到容器中
StringBuffer insert(int offset, boolean/...) 指定索引值位置来插入数据

删:

方法名 说明
StringBuffer delete(int start, int end) 指定开始索引值与结束索引值来删除容器中的数据
StringBuffer deleteCharAt(int index) 指定索引值删除一个字符

改:

方法名 说明
StringBuffer replace(int start, int index, String str) 指定开始索引值与结束索引值替换新的字符串内容
StringBuffer reverse() 翻转内容
void setCharAt(int index, char ch) 指定索引值替换字符
String substring(int start, int end) 指定开始索引值与结束索引值截取内容
void ensureCapacity(int minimunCapacity) 指定字符串缓冲类的字符数组长度。(基本不用)

查:

方法名 说明
indexOf(String str, int fromIndex) 查找子串第一次出现的索引值
lastIndexOf(String str) 查找子串最后一次出现的索引值
capacity() 查看当前(底层)字符数组的长度
length() 查看字符长度
charAt(int Index) 根据索引值查看字符
toString() 把字符串缓冲类的内容转换成字符串

StringBuilder 类

StringBuilder 概述

StringBuilder 是一个可变的字符串类,我们可以把它看成是一个容器,这里的可变指的是StringBuilder 对象中的内容是可变的

StringBuilder 常用方法与 StringBuffer 常用方法一致。

public class Test{
    public static void main(String[] args) {
        // 创建对象
        StringBuilder sb = new StringBuilder();

        // public StringBuilder append(任意类型):添加数据,并返回对象本身
//        StringBuilder sb2 = sb.append("hello");
//
//        System.out.println("sb:" + sb);
//        System.out.println("sb2:" + sb2);
//        System.out.println(sb == sb2);

//        sb.append("hello");
//        sb.append("world");
//        sb.append("java");
//        sb.append(100);

        // 链式编程
        sb.append("hello").append("world").append("java").append(100);
        System.out.println("sb:" + sb);  // helloworldjava100

        // public StringBuilder reverse():返回逆序的字符序列
        sb.reverse();
        System.out.println("sb:" + sb);  // 001avajdlrowolleh
		
        // StringBuilder 转换为 String
        StringBuilder sb2 = new StringBuilder();
        sb2.append("hello");
        String s2 = sb2.toString();
        System.out.println(s2);

        // String 转换为 StringBuilder
        String s3 = "hello";
        StringBuilder sb3 = new StringBuilder(s2);
        System.out.println(sb2);
    }
}

StringBuffer、StringBuilder、String 三者异同

  1. String 为字符串常量,而 StringBuffer、StringBuilder 均为字符串变量,即 String 一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。

  2. StringBuffer 是线程安全的,而 StringBuilder 则没有实现线程安全,因此执行速度较高。

    • 一个 StringBuffer 对象在字符串缓冲区被多个线程使用时,StringBuffer 中的很多方法都带有 Synchronized 关键字,所以可以保证线程是安全的;但 StringBuilder 的 append() 方法中没有 Synchronized 关键字,所以不能保证线程安全。
    • 因此如果要进行的操作是多线程的,那么建议使用 StringBuffer;单线程下则建议使用速度较快的 StringBuilder。
上一篇:[LeetCode]面试题 01.03. URL化


下一篇:Java基础学习笔记-代码块、API、Objects和String StringBuilder