字符串

1. String

构造器

  • public String() :初始化新创建的 String对象,以使其表示空字符序列。
  • String(String original): 初始化一个新创建的 String 对象,使其表示一个与参数相同的字符序列;换句话说,新创建的字符串是该参数字符串的副本。
  • public String(char[] value) :通过指定的字符数组来构造新的String
  • public String(char[] value,int offset, int count) :通过字符数组的一部分来构造新的String
  • public String(byte[] bytes) :通过使用平台的默认字符集解码指定的字节数组来构造新的String
  • public String(byte[] bytes,String charsetName) :通过使用指定的字符集解码指定的字节数组来构造新的String

String与其他结构间的转换

字符串 —-> 基本数据类型、包装类

  • 包装类的public static xxx parseXxx(String s):可将“数字”字符组成的字符串转换为基本数字类型。
  • 调用 Xxx.parseXxx(str) 方法。

基本数据类型、包装类 —-> 字符串

  • String类的public static String valueOf(xxx n)可将基本数字类型转换为字符串
  • 调用 String.valueOf(xxx) 方法。

字符串 —-> 字节数组(编码)

  • public byte[] getBytes() :使用平台默认字符集将此 String 编码为 byte 序列,并返回 一个byte 数组。
  • public byte[] getBytes(String charsetName) :使用指定字符集将此 String 编码到 byte 序列,并返回 一个byte 数组。

字节数组 —-> 字符串(解码):

  • String(byte[]):通过使用平台默认字符集解码指定的 byte 数组,构造一个新的 String
  • String(byte[],int offset,int length) :用指定的字节数组的一部分,即从数组起始位置offset开始取length个字节构造一个字符串对象。
  • String(byte[], String charsetName ) : 解码,按照指定的编码方式进行解码。
  • String(byte[] bytes, int offset, int length, Charset charset): 解码,按照指定的编码方式从offset索引处进行解码length个字节。

常用的方法 int 或 char 或 char[]

  • int length():返回字符串的长度。

  • char charAt(index):返回[index]位置的字符。

  • char[] toCharArray():将此字符串转换为一个新的字符数组返回。

  • int compareTo(String other):比较字符串大小,区分大小写,按照Unicode编码值比较大小。

  • int compareToIgnoreCase(String other):比较字符串大小,不区分大小写。

  • int codePointAt(int):返回指定索引的字符的默认字符集的编码值。

  • int codePointBefore(int):返回指定索引前一个的字符的默认字符集的编码值。

  • int codePointCount(int, int):用于计算指定字符序列中指定范围内的代码点数量。

    public class CodePointCountExample {
    public static void main(String[] args) {
    String str = "Hello, World!";
    int codePointCount = str.codePointCount(0, str.length());
    System.out.println("代码点数量: " + codePointCount);
    }
    }

逻辑判断的方法 boolean

  • boolean contains(CharSequence s):是否包含s(实现了CharSequence接口)。

  • boolean contentEquals(CharSequence s)boolean contentEquals(StringBuffer s):是否和s内容一致(不常用!)。

    public class ContentEqualsExample {
    public static void main(String[] args) {
    String str = "Hello, World!";
    CharSequence cs = "Hello, World!";

    // 使用 contentEquals 方法比较字符串和字符序列
    boolean isEqual = str.contentEquals(cs);

    // 输出比较结果
    System.out.println("字符串和字符序列是否相等: " + isEqual);
    }
    }
    /*contentEquals 方法比较的是字符序列的内容,而不是引用。即使两个字符序列是不同的对象,但只要它们的内容相同,contentEquals 方法就会返回 true。(不常用!)*/
  • boolean endsWith(String):测试此字符串是否以指定的后缀结束 。

  • boolean equals(Object):比较字符串是否相等,区分大小写。

  • boolean equalsIgnoreCase(Object):比较字符串是否相等,不区分大小写。

  • boolean isBlank():字符串是否为空或只含有空白符号如\t \n等。

  • boolean isEmpty():字符串是否为空。

  • boolean mathes(String):字符串是否匹配指定的正则表达式。

  • boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len) :比较两个字符串的指定区域是否相等。

    • ignoreCase:一个布尔值,表示是否忽略大小写进行比较。如果为 true,则比较时不区分大小写;如果为 false,则区分大小写。

    • toffset:当前字符串中要比较的起始位置。

    • other:要与当前字符串进行比较的另一个字符串。

    • ooffsetother 字符串中要比较的起始位置。

    • len:要比较的字符数量。

      public class RegionMatchesExample {
      public static void main(String[] args) {
      String str1 = "Hello, World!";
      String str2 = "hello, world!";

      // 忽略大小写比较指定区域是否相等
      boolean isEqual1 = str1.regionMatches(true, 0, str2, 0, 5);

      // 区分大小写比较指定区域是否相等
      boolean isEqual2 = str1.regionMatches(false, 0, str2, 0, 5);

      // 输出比较结果
      System.out.println("忽略大小写比较指定区域是否相等: " + isEqual1);
      System.out.println("区分大小写比较指定区域是否相等: " + isEqual2);
      }
      }
      /*如果区分大小写,则等价于以下的重载方法*/
  • boolean regionMatches(int toffset, String other, int ooffset, int len):比较两个字符串指定区域是否相等。

  • boolean startsWith(String):测试此字符串是否以指定的前缀开始 。

  • boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始

返回索引的方法 int

  • int indexOf(String)int indexOf(int ch):从前往后找当前字符串中为指定的String或值为ch的字符,即如果有返回第一次出现的下标,要是没有返回-1。
  • int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始。
  • int lastIndexOf(String)int lastIndexOf(int ch):从后往前找当前字符串中为指定的String或值为ch的字符,即如果有返回最后一次出现的下标,要是没有返回-1。
  • int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。

字符串处理的方法 String 或 String[]

  • String concat(String):将指定的字符串连接到当前字符串的末尾。
  • String indent(int):在字符串的每一行前面添加指定数量的空格
  • String intern():返回字符串对象在字符串常量池中的引用。
  • String repeat(int):重复当前字符串指定的次数
  • String replace(char, char)String replace(CharSequence, CharSequence):用指定的字符或字符序列替换字符串中的所有匹配项。
  • String replaceAll(String, String): 用指定的字符串替换字符串中的所有匹配正则表达式的部分。参数是正则表达式和替换后的字符串。
  • String replaceFirst(String, String):用指定的字符串替换字符串中第一个匹配正则表达式的部分。
  • String[] split(String)String[] split(String, int):根据指定的分隔符指定分割的次数(可选)将字符串分割成字符串数组
  • String[] splitWithDelimiters(String, int):根据指定的分隔符指定分割的次数将字符串分割成字符串数组,该数组含有分隔符
  • String strip():去除字符串两端的空格。
  • String stripIndent():去除字符串每行开头的空格。每行只能去除相同数量的空格。
  • String stripLeading():去除字符串开头的空格。
  • String stripTrailing():去除字符串结尾的空格。
  • String substring(int)String substring(int, int):提取、截取字符串从指定的起始索引(包含)到结束索引(不包含)的子串。
  • String toLowerCase() String toLowerCase(Locale):将字符串转换为小写。Locale(可选)是区域设置。
  • String toString():返回字符串本身。
  • String toUpperCase()String toUpperCase(Locale):将字符串转换为大写。Locale(可选)是区域设置。
  • String translateEscapes():将字符串中的转义字符转换为对应的字符。
  • String trim():去除字符串两端的空格和其他空白字符。
  • static String copyValueOf(char[])static String copyValueOf(char[], int):将指定的字符数组起始索引转换为字符串。
  • static String join(CharSequence, CharSequence...):使用指定的分隔符多个字符序列连接成一个字符串。
  • static String valueOf(xxx):可将基本数字类型转换为字符串。

字符串格式化 String

format方法

  • static String format(String, Object …)static String format(Locale, String, Object …)`:使用指定的格式字符串对象来格式化字符串,返回处理好的字符串。

  • static String formatted(Object ...):使用默认的格式字符串和要格式化的对象来格式化字符串。

    该方法最终调用 java.util.Formatter 类的 format 方法。

    public static String format(String format, Object... args) {
    return new Formatter().format(format, args).toString();
    }

    public static String format(Locale l, String format, Object... args) {
    return new Formatter(l).format(format, args).toString();
    }

    参考 Java Api 中关于 Formatter,可以发现 format 方法的第一个参数是有固定格式的。其格式如下:

    %[argument_index$][flags][width][.precision]conversion

    argument_index: 可选,是一个十进制整数,用于表明参数在参数列表中的位置。

    flags: 可选,用来控制输出格式

    width: 可选,是一个正整数,表示输出的最小长度

    precision:可选,用来限定输出的精度

    conversion:必须,用来表示如何格式化参数的字符

argument_index

  • argument_index是可选参数,用于表明参数在参数列表中的位置。

  • 第一个参数由 “1$“ 引用,第二个参数由 “2$“ 引用,依此类推。

    String.format("大家好,我叫:%1$s,今年:%2$d岁。%1$s是%3$s的爸爸。", "小明", 25, "小小明");

flags

  • flags是可选参数,用于控制输出的格式,比如左对齐、金额用逗号隔开。

  • '-' :在最小宽度内左对齐,不可以与“用0填充”同时使用

  • ' ' :正值前加空格,负值前加负号

  • '0' :结果将用零来填充

  • ',' :每3位数字之间用“,”分隔(只适用于fgG的转换)

  • '(': 若参数是负数,则结果中不添加负号而是用圆括号把数字括起来(只适用于eEfgG的转换)

    String.format("设置最小宽度为8为,左对齐。%-8d:%-8d:%-8d%n", 1, 22, 99999999);
    String.format("'0':结果将用零来填充。设置最小宽度为8,%08d:%08d:%08d", 1, -22, 99999990);
    String.format("'+':结果总是包括一个符号。%+d:%+d:%+d", 1, -2, 0);
    String.format("' ':正值前加空格,负值前加负号。% d:% d:% d", 1, -2, 0);
    String.format("',':每3位数字之间用“,”分隔(只适用于fgG的转换)。%,d:%,d:%,d", 1, 100, 1000);
    String.format("'(':若参数是负数,则结果中不添加负号而是用圆括号把数字括起来(只适用于eEfgG的转换)。%(d:%(d", 1, -1);

width

  • width是可选参数,用于控制输出的宽度,不能为0。(常和flags中的'0'一起使用)

  • 数值作为参数

    String.format("设置最小宽度为8,不满8位用0填充:%08d:%08d", 1, -10000000);

precision

  • precision是可选参数,用来限定输出的精度,用于浮点数。

  • .数值作为参数

    String.format("设置精度为2位:%.2d", 1);

conversion

符号 适用参数类型 说明
'a' / 'A' 浮点数 以16进制输出浮点数
'b' / 'B' 任意值 如果参数为 null 则输出 false,否则输出 true
'c' / 'C' 字符或整数 输出对应的 Unicode 字符
'd' 整数 对整数进行格式化输出
'e' / 'E' 浮点数 以科学记数法输出浮点数
'f' 浮点数 对浮点数进行格式化输出
'g' / 'G' 浮点数 以条件来决定是否以科学记数法方式输出浮点数
'h' / 'H' 任意值 以 16 进制输出参数的 hashCode() 返回值
'o' 整数 以8进制输出整数
's' / 'S' 字符串 对字符串进行格式化输出
't' / 'T' 日期时间 对日期时间进行格式化输出(具体参数见Calender类)
'x' / 'X' 整数 以16进制输出整数
'n' 换行符
'%' 百分号本身

时间日期格式化 String

参考 Java Api 中关于 Date/Time Conversions,可以发现时间日期格式化是有固定格式的。其格式如下:

%[argument_index$][flags][width]conversion
//相对于普通的格式,时间日期格式化少了 precision
//而 conversion 是由两个字符组成,且第一个字符固定为 t 或 T 。
  1. 以下转换字符用于格式化时间

    Conversion Description
    'H' 24小时制中的小时,格式为两位数字,必要时前缀为零,即 00 - 23
    'I' 12小时制中的小时,格式为两位数字,必要时前缀为零,即 01 - 12
    'k' 24小时制中的小时,即 0 - 23
    'l' 2小时制中的小时,即 1 - 12
    'M' 1小时内的分钟,格式为两位数字,必要时前缀为零,即 00 - 59.
    'S' 1分钟内的秒钟,格式为两位数字,必要时前缀为零,即 00 - 60 (“60“是支持LEAP秒所需的特殊值)。
    'L' 1秒钟内的毫秒,格式为三位数字,必要时前缀为零,即000 - 999
    'N' 1秒钟内的纳秒,格式为九位数字,必要时前缀为零,即000000000 - 999999999
    'p' 小写'p'的区域特定的上午或下午标记,如ampm。使用转换前缀'T'强制将此输出转换为大写,如AMPM
    'z' RFC 822 风格的数字时区偏离 GMT,例如 -0800。这个数值会因应夏时制的需要而作出调整。对于 Long、 Long 和 Date,所使用的时区是 Java 虚拟机实例的默认时区。
    'Z' 表示时区缩写的字符串。这个数值会因应夏时制的需要而作出调整。对于 Long、 Long 和 Date,所使用的时区是 Java 虚拟机实例的默认时区。Formatter 的区域设置将取代参数的区域设置(如果有的话)。
    's' 自1970年1月1日开始以来的秒数。
    'Q' 自1970年1月1日开始以来的毫秒数。
  2. 以下转换字符用于格式化日期

    Conversion Description
    'B' 特定地区的月份全称,如"January", "February"
    'b' 特定地区的月份简称,如 "Jan", "Feb"
    'h' 和转义字符 'b'一致。
    'A' 特定地区的星期全称,如"Sunday", "Monday"
    'a' 特定地区的星期简称,如 "Sun", "Mon"
    'C' 年份的前两个数字,必要时前缀为零,即 00 - 99
    'Y' 四位数的年份,必要时前缀为零,即 0000 - 9999
    'y' 年份的后两个数字,必要时前缀为零,即00 - 99
    'j' 一年中的天数,必要时前缀为零,即001 - 366
    'm' 一年中的月份,必要时前缀为零,即01 - 13
    'd' 一月中的天数,必要时前缀为零,即01 - 31
    'e' 一月中的天数,即1 - 31
  3. 以下转换字符用于格式化共同的日期/时间

    Conversion Description
    'R' 24小时制的时间格式为 "%tH:%tM"
    'T' 24小时制的时间格式为 "%tH:%tM:%tS"
    'r' 12小时制的时间格式为 "%tI:%tM:%tS %Tp"。上午或下午标记的位置(%Tp)可能依赖于地区。
    'D' 日期的格式为"%tm/%td/%ty"
    'F' ISO 8601完整日期格式为 "%tY-%tm-%td"
    'c' 日期时间格式为 "%ta %tb %td %tT %tZ %tY",如"Sun Jul 20 16:17:00 EDT 1969"

2. StringBuffer、StringBuilder

  • 因为String对象是不可变对象,虽然可以共享常量对象,但是对于频繁字符串的修改和拼接操作,效率极低,空间消耗也比较高。因此,JDK又在java.lang包提供了可变字符序列StringBuffer和StringBuilder类型。
  • java.lang.StringBuffer 、 StringBuilder代表可变的字符序列,JDK1.0中声明,可以对字符串内容进行增删,此时不会产生新的对象。
  • StringBuilder 和 StringBuffer 非常类似,均代表可变的字符序列,而且提供相关功能的方法也一样。
  • 区分String、StringBuffer、StringBuilder。
    • String:不可变的字符序列; 底层使用byte[]数组存储。
    • StringBuffer:可变的字符序列;线程安全(方法有synchronized修饰),效率低;底层使用byte[]数组存储 。
    • StringBuilder:可变的字符序列; jdk1.5引入,线程不安全的效率高;底层使用byte[]数组存储。

构造器

  • StringBuffer() / StringBuilder() :默认创建一个长度为16的byte[]。
  • StringBuffer(int) / StringBuilder(int): 创建指定长度的byte[]。
  • StringBuffer(String) / StringBuilder(String) :创建字符串长度+16的byte[]。

常用的方法 int String void

  • int length():返回存储的字符数据的长度。
  • int compareTo(StringBuffer):比较字符串大小,区分大小写,按照Unicode编码值比较大小。
  • int codePointAt(int):返回指定索引的字符的默认字符集的编码值。
  • int codePointBefore(int):返回指定索引前一个的字符的默认字符集的编码值。
  • int codePointCount(int, int):用于计算指定字符序列中指定范围内的代码点数量。
  • String toString():返回此序列中数据的字符串表示形式。
  • void setLength(int newLength) :设置当前字符序列长度为newLength。
  • String substring(int start):从指定索引到最后截取当前字符序列。
  • String substring(int start, int end)从始索引到尾索引截取当前字符序列。

增、删、改、查、插、转

  • 增加
    • StringBuffer append(xx):提供了很多的append()方法,用于进行字符串追加的方式拼接。
  • 删除
    • StringBuffer delete(int start, int end):删除[start,end)之间字符。
    • StringBuffer deleteCharAt(int index):删除指定索引位置字符。
  • 修改
    • StringBuffer replace(int start, int end, String str):替换[start,end)范围的字符序列为str
    • void setCharAt(int index, char c):替换指定索引反转位置处的字符为'c'
  • 查找
    • char charAt(int index):查找指定索引位置上的字符。
    • int codePointAt(int):返回指定索引的字符的默认字符集的编码值。
  • 插入
    • StringBuffer insert(int index, xx):提供了很多的insert()方法,在指定索引的位置插入xx。
  • 反转
    • StringBuffer reverse():将原字符串反转。

比较器

1. Comparable

  • Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序
  • 实现 Comparable 的类必须实现 compareTo(Object obj) 方法,两个对象即通过 compareTo(Object obj) 方法的返回值来比较大小。
package java.lang;

public interface Comparable{
int compareTo(Object obj);
}
  • 实现Comparable接口的对象列表(和数组)可以通过 Collections.sortArrays.sort进行自动排序。实现此接口的对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。
  • Comparable 的典型实现:(默认都是从小到大排列的)
    • String:按照字符串中字符的Unicode值进行比较
    • Character:按照字符的Unicode值来进行比较
    • BigInteger、BigDecima、包装类:按照它们对应的数值大小进行比较
    • Boolean:true 对应的包装类实例大于 false 对应的包装类实例
    • Date、Time等:后面的日期时间比前面的日期时间大

2. Comparator

  • 思考

    • 当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码。

      (例如:一些第三方的类,你只有.class文件,没有源文件)

  • JDK在设计类库之初,也考虑到这种情况,所以又增加了一个java.util.Comparator接口。强行对多个对象进行整体排序的比较。

    • 重写compare(Object o1,Object o2)方法,比较o1和o2的大小:如果方法返回正整数,则表示o1大于o2;如果返回0,表示相等;返回负整数,表示o1小于o2。
    • 可以将 Comparator 传递给 sort 方法(如 Collections.sortArrays.sort),从而允许在排序顺序上实现精确控制。
package java.util;

public interface Comparator{
int compare(Object o1,Object o2);
}

举例:

package com.atguigu.api;

import java.util.Comparator;
//定义定制比较器类
public class StudentScoreComparator implements Comparator {
@Override
public int compare(Object o1, Object o2) {
Student s1 = (Student) o1;
Student s2 = (Student) o2;
int result = s1.getScore() - s2.getScore();
return result != 0 ? result : s1.getId() - s2.getId();
}
}