【Java】字符串常用操作

三者区别

StringBuilder和StringBuffer非常相似,均代表可变的字符序列,而且方法也一样。

  • String:不可变字符序列
  • StringBuffer:可变字符序列、效率低、线程安全
  • StringBuilder:可变字符序列、效率高、线程不安全

    由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。

这里顺带讲讲String的使用陷阱:

String s = "a"; 
s = s + "b";

在相加的时候,实际上原来的 "a" 字符串对象已经丢弃了,现在又产生了一个字符串 s+"b" (也就是"ab")。
如果多次执行这些改变串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。如果这样的操作放在循环中,会极大影响程序的性能。

StringBuilder和StringBuffer的常用方法

注意:不能直接用扫描器输入StringBuilder和StringBuffer,需要构造函数
只能StringBuilder sb = new StringBuilder(in.next());
而不能像String一样,String str = in.next();

StringBuilder和StringBuffer的方法一样,以下列出了StringBuffer的常用方法:

方法 返回类型 描述 备注
append(String str) StringBuffer 追加内容 此方法可以添加任何数据类型
insert(int offset, String str) StringBuffer 在指定位置处插入指定字符
reverse() StringBuffer 将内容反转保存
replace(int start, int end, String str) StringBuffer 指定内容替换
delete(int start, int end) StringBuffer 删除指定范围的字符串
substring(int start) String 字符串截取,指定开始点
substring(int start, int end) String 截取指定范围的字符串
indexOf(String str) int 查找指定字符串是否存在,返回索引号
indexOf(String str, int fromIndex) int 从指定位置开始查找指定字符是否存在,返回索引号
length() int 求出内容长度
toString() String 将内容变为String类型 继承Object类的方法

String的常用方法

String类用来存储字符串。
例如:

String a = "Hello"; 
方法 返回类型 描述 备注
toCharArray() char[] 将一个字符串变为字符数组 字符串→字符数组
charAt() char 将指定索引处的字符返回 字符
getBytes() byte[] 使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中
length() int 返回此字符串的长度 长度
indexOf(String str) int 返回指定子字符串在此字符串中第一次出现处的索引(若没有,返回-1) 可以用来查找此子字符串是否存在
indexOf(String str, int fromIndex) int 返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
trim() String 返回字符串的副本,忽略前导空白和尾部空白
replace(char oldChar, char newChar) String 用 newChar 替换此字符串中出现的所有 oldChar replace(" ","")可以用来去掉所有空格
substring(int beginIndex) String 对字符串进行截取,从begin开始,到结尾结束
substring(int begin, int end) String 对字符串区间[begin, end)进行截取 子字符串
equals(String str) boolean 判断两个字符串是否相等
equalsIgnoreCase(String str) boolean 不区分大小写比较两个字符串是否相等
toUpperCase() String 将一个字符串全部变成大写字母
toLowerCase() String 将一个字符串全部变为小写字母
startsWith(String prefix) boolean 判断是否以指定字符串开头
endsWith(String suffix) boolean 判断是否以指定字符串结尾
split(String regex) String[] 按指定的正则表达式、分隔字符或字符串对内容进行分割,并将分割后的结果作为字符串数组返回 分割字符串
matches(String regex) boolean 告知此字符串是否匹配给定的正则表达式
replaceAll(String regex, String replacement) String 使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串

字符串连接

可以直接用+号,如

String a = "Hello"; 
String b = "world"; 
System.out.println(a + ", " + b + "!"); // output "Hello, world!" 

字符串查找

String提供了两种查找字符串的方法,即 indexOf()lastIndexOf() 方法。

  • indexOf(String s)用于返回参数字符串 s 在指定字符串中首次出现的索引位置
    当调用字符串的indexOf()方法时,会从当前字符串的开始位置搜索 s 的位置。
    • 如果没有检索到字符串 s,该方法返回-1
    String str ="We are students";
    int size = str.indexOf("a"); // 变量 size 的值是 3 
  • lastIndexOf(String str)用于返回字符串最后一次出现的索引位置。
    当调用字符串的lastIndexOf()方法时,会从当前字符串的开始位置检索参数字符串 str,并将最后一次出现 str 的索引位置返回。
    • 如果没有检索到字符串 str,该方法返回-1
    • 如果lastIndexOf()方法中的参数是空字符串"",则返回的结果与 length 方法的返回结果相同。

获取指定索引位置的字符

使用charAt()方法可将指定索引处的字符返回。

String str = "Hello world";
char mychar = str.charAt(5); // mychar 的结果是 w 

获取子字符串

通过String类substring()方法可对字符串进行截取。

这些方法的共同点就是都利用字符串的下标进行截取,且应明确字符串下标是从 0 开始的。在字符串中空格占用一个索引位置。

  • substring(int beginIndex)从begin开始,到结尾结束

    String str = "Hello world";
    String substr = str.substring(3); //获取字符串,此时 substr 值为 lo world
  • substring(int beginIndex, int endIndex)begin和end区间是前闭后开的,[begin, end)

    注意:其实这个区间前闭后开针对字符来说的,看下面举的例子,0~3截取了Hel这三个字符,即 [0, 3),第0、1、2个字符。

    • beginIndex:开始截取子字符串的索引位置
    • endIndex:子字符串在整个字符串中的结束位置

    理解:但是,我们可以从存储机制去理解它。
    Hello World 在系统里是这样存储的:

    我们截取了地址0~3,所以截取了Hel这三个字符。

    String str = "Hello world";
    String substr = str.substring(0,3); //substr 的值为 Hel

去除空格

trim()方法返回字符串的副本,清除了左右两端的空格

String str = "        hello           ";
System.out.println(str.trim());
//程序运行结果:hello

字符串替换

replace(String oldChar,String newChar)方法可实现将指定的字符或字符串替换成新的字符或字符串。

  • oldChar:要替换的字符或字符串
  • newChar:用于替换原来字符串的内容

注意:如果要替换的字符 oldChar 在字符串中重复出现多次,replace()方法会将所有 oldChar 全部替换成 newChar。需要注意的是,要替换的字符 oldChar 的大小写要与原字符串中字符的大小写保持一致。

String str= "address";
String newstr = str.replace("a", "A");// newstr 的值为 Address

判断字符串是否相等(切不可使用==)

  • equals(String otherstr)
    如果两个字符串具有相同的字符和长度,则使用equals()方法比较时,返回 true。

    注意:equals()方法比较时,区分大小写

  • equalsIgnoreCase(String otherstr)

    注意:equalsIgnoreCase()方法与equals()类似,不过在比较时忽略了大小写

equals()与==的区别:

  • ==:
    • 如果作用于基本数据类型的变量(如 byte,short,char,int,long,float,double,boolean),则直接比较其存储的“值”是否相等
    • 如果作用于引用类型的变量(如 String类),则比较的是所指向的对象的地址(即 是否指向同一个对象)。
  • equals()方法:是基类Object中的方法,因此对于所有的继承于Object的类都会有该方法。在Object类中,equals()方法是用来比较两个对象的引用是否相等,即 是否指向同一个对象。

是不是感觉equals()在Object类中跟==好像是一样的描述啊??没错,就是一样的,不是我写错了!

Java中Object类是所有类的父类,它里面定义了equals()方法:

public boolean equals(Object obj) {
    return (this == obj);
}

若object1.equals(object2)为true,则表示equals1和equals2实际上是引用同一个对象。

注意:对于equals()方法,equals()方法不能作用于基本数据类型的变量。

  • 如果没有对equals()方法进行重写,则比较的是引用类型的变量所指向的对象的地址;
  • String类对equals方法进行了重写,用来比较指向的字符串对象所存储的字符串内容是否相等
    其他的一些自带的引用数据类型,如 Double,Date,Integer等,都对equals()方法进行了重写,用来比较指向的对象所存储的内容是否相等

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

compareTo()方法为按字典顺序比较两个字符串,该比较基于字符串中各个字符的 Unicode 值,按字典顺序将此 String 对象表示的字符序列与参数字符串所表示的字符序列进行比较。

  • 如果按字典顺序此 String 对象位于参数字符串之前,则比较结果为一个负整数
  • 如果按字典顺序此 String 对象位于参数字符串之后,则比较结果为一个正整数
  • 如果这两个字符串相等,则结果为0.

字母大小写转换

  • 字符串的toLowerCase()方法可将字符串中的所有字符从大写字母改写为小写字母,
  • toLowerCaseUpperCase()方法可将字符串中的小写字母改写为大写字母。
str.toLowerCase();
str.toUpperCase();

字符串分割

使用split()方法可以使字符串按指定的分隔字符或字符串对内容进行分割,并将分割后的结果作为字符串数组返回。

str.split(String regex);:regex为分割字符串的分割符,也可以使用正则表达式。

注意:没有统一的对字符串进行分割的符号,如果想定义多个分割符,可使用符号“|”。(这个是正则表达式的“或”概念)

例如,“,|=”表示分割符分别为“,”和“=”。

String str = "hello world";
String[] s = str.split(" ");
for(int i=0; i<s.length; i++) {
    System.out.println(s[i]);
}

程序运行结果:

hello
world

总结

总结:

  • 如果要操作少量的数据用 String;
  • 多线程操作字符串缓冲区下操作大量数据 StringBuffer;
  • 单线程操作字符串缓冲区下操作大量数据 StringBuilder。
字符串 字符序列 效率 线程 线程安全 备注
String 不可变 String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且浪费大量优先的内存空间
StringBuffer 可变 多线程操作字符串 线程安全 StringBuffer是可变类,和线程安全的字符串操作类,任何对它指向的字符串的操作都不会产生新的对象。每个StringBuffer对象都有一定的缓冲区容量,当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自动增加容量
StringBuilder 可变 单线程操作字符串 线程不安全 可变类,速度更快
原文地址:https://www.cnblogs.com/blknemo/p/12490281.html