Java中String相关知识复习

一、字符串基本知识

1.String对象的创建

直接创建一个常量String对象,结果如下:
在这里插入图片描述
创建常量字符串和创建字符串对象的区别,如下图:
在这里插入图片描述
实际上,字符串常量存储在字符串常量池,目的是为了共享;而字符串非常量对象存储在堆中。
在这里插入图片描述
s1和s2都是常量字符串,用等号比较直接比的都是值。
s3和s4都是字符串对象,即使它们的值相等,但是地址不一样,所以等号为false

2.字符串的特性

在这里插入图片描述
常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量。
只要其中一个是变量,结果就在堆中。
如果拼接的结果调用intern方法,返回值就在常量池中。

在这里插入图片描述

3.字符串相关方法

方法说明
char charAt(int index)返回某索引处的字符return value[index]
boolean isEmpty()判断是否是空字符串:return value.length == 0
String toLowerCase()将 String 中的所有字符转换为小写
String toUpperCase()将 String 中的所有字符转换为大写
String trim()返回字符串的副本,忽略前导空白和尾部空白
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)测试此字符串从指定索引开始的子字符串是否以指定前缀开始
int indexOf(String str)返回指定子字符串在此字符串中第一次出现处的索引
int indexOf(String str, int fromIndex)返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
int lastIndexOf(String str)返回指定子字符串在此字符串中最右边出现处的索引
int lastIndexOf(String str, int fromIndex)返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索
String replace(char oldChar, char newChar)返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的
String replaceAll(String regex, String replacement)使 用 给 定 的replacement 替换此字符串所有匹配给定的正则表达式的子字符串
String replaceFirst(String regex, String replacement)使 用 给 定 的replacement 替换此字符串匹配给定的正则表达式的第一个子字符串
String[] split(String regex)根据给定正则表达式的匹配拆分此字符串

4.String与基本数据类型的转换

1)字符串转换为基本数据类型或包装类:
public static int parseInt(String s)
2)基本数据类型转换为字符串:
调用String类的public String valueOf(int n)可将int型转换为字符串
3)字符数组转换为字符串:
String 类的构造器:String(char[]) 和 String(char[],int offset,int length) ,分别用字符数组中的全部字符和部分字符创建字符串对象。
4)字符串转换为字符数组:
public char[] toCharArray():将字符串中的全部字符存放在一个字符数组中的方法
public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin):提供了将指定索引范围内的字符串存放到数组中的方法
5)字节数组转换为字符串:
String(byte[]):通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String
6)字符串转换为字节数组
public byte[] getBytes() :使用平台的默认字符集将此 String 编码为byte 序列,并将结果存储到一个新的 byte 数组中
public byte[] getBytes(String charsetName) :使用指定的字符集将 此 String 编码到 byte 序列,并将结果存储到新的 byte 数组

二、字符串相关的类

1.StringBuffer类

1.1 StringBuffer类介绍

java.lang.StringBuffer代表可变的字符序列,JDK1.0中声明,可以对字符串内容进行增删,此时不会产生新的对象
它的底层代码:
在这里插入图片描述

1.2 StringBuffer类创建

StringBuffer类必须用构造器生成,它有三个构造器:

构造器说明
StringBuffer()初始容量为16的字符串缓冲区
StringBuffer(int size)构造指定容量的字符串缓冲区
StringBuffer(String str)将内容初始化为指定字符串内容,此时容量为字符串长度+16

1.3 StringBuffer类常用方法

方法说明
StringBuffer append(xxx)用于进行字符串拼接
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()把当前字符序列逆转

在使用append和insert方法时,如果原来value数组长度不够,可以扩容

2.StringBuilder类

2.1 StringBuilder类介绍

StringBuilder和StringBuffer很相似,也是可变的字符序列,功能也一样。

3.String、StringBuffer和StringBuilder对比

String:不可变字符序列
StringBuffer:可变字符序列、效率低、线程安全(扩容方法中有关键字synchronized)
StringBuilder:可变字符序列、效率高、线程不安全(扩容方法没有关键字synchronized)

扩容问题:
如果要添加的数据底层数组存储不下了,就需要扩容底层的数组。
默认情况下,扩容为原来容量的2倍+2,同时将原有数组中的元素复制到新的数组中;如果容量还不够,直接选取需要的容量大小作为新的容量。

开发建议:
在需要多次修改字符串的情况下,String效率最低,不建议使用;建议使用StringBuffer(int capacity)或StringBuilder(int capacity)方法,考虑线程安全问题选取。

StringBuilder线程不安全原因:
StringBuilder里的成员变量:

// 存储的字符串(通常情况一部分为字符串内容,一部分为默认值)
char[] value;

// 数组已经使用数量
int count;

StringBuilder中的方法是没有synchronized这个关键字的,它的append方法中的count+=len导致了线程不安全,当多个线程都要使用append进行添加字符串时,count会增加,如果被同时读取到一个值,那么改变后的结果就不正确了:

public AbstractStringBuilder append(String str) {
    if (str == null)
        return appendNull();
    int len = str.length();
    ensureCapacityInternal(count + len);
    str.getChars(0, len, value, count);
    count += len;
    return this;
}

在后面调用getChars时,因为count不正确,所以可能发生越界异常的情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值