String类

一.创建字符串

常见构造String类的方式

//方式1.
String s1 = "Hello word";
//方式2.
String s2 = new String("Hello word");
//方式3.
char[] array = {'a','b','c'};
String s3 = new String(array);

注意:

  • “hello”这样的字符串字面值常量,类型也是String
  • String是引用类型
    String 在底层的 存储方式:
    在这里插入图片描述

二.比较字符串相等

如果说两个 int 比较大小:

int a = 10;
int b = 10;
System.out.println(a == b);
//true

但是两个 String 比较大小:

String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2);
//true

看起来没什么问题,但是 :

String s3 = new String("hello");
String s4 = new String("hello");
System.out.println(s3 == s4);
//false

来看一下 两个代码的 内存布局:
在这里插入图片描述
s1s2 都指向的是 常量池中的hello ,指向的是同一个对象
在这里插入图片描述
然而 s3s4 都是 new 出来的String 对象 所有存放在堆中 分别指向的是不同的对象
String使用==比较的是两个引用是否指向同一个对象,而不是字符串的内容
如果想比较字符串内容 可以使用equals()方法

String s5 = new String("hello");
String s6 = new String("hello");
System.out.println(s5.equals(s6));
//true

三.字符串常量池

JVM底层实际上维护了一个字符串常量池:

  • 如果采用直接赋值的模式给String类的对象实例化操作,那么这个字符串内容将会自动保存在这个常量池中
  • 如果下次继续使用直接赋值的模式声明String类,如果常量池中有,将直接进行引用
  • 如果没有,则开辟新的字符串对象而保存在常量池中,以便于下次使用

我们可以使用 Stringintern 方法手动把String对象加入到字符串常量池中

解释String类两种对象实例化的区别
1.直接赋值:只会开辟一段堆内存空间,并且该字符串对象可以自动保存在字符串常量池中,以供下次使用
2.构造方法:会开辟两块堆内存空间,其中一块成为垃圾空间,不会自动保存在对象池中,可以使用intern方法手工入池
我们一般使用直接赋值的方式创建String对象

四.理解字符串不可变

String类的内部实现也是基于char[]来实现的,但是String类并没有提供set方法之类的来修改内部的字符数组
比如:

String s1 = "hello";
s1 = s1 +  "word";
s1 += "!!!";
System.out.println(s1);
//执行结果
hello word !!!

+=看起来像是修改了字符串 其实不是,内存变化如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
+= 之后s1打印的结果变了,但是 不是 String 对象本身发生变化,而是s1引用了其他的对象
如果需要改字符串,那就需要借助原字符串,创建新的字符串

String str = "Hello";
str = "h" + str.substring(1);
System.out.println(str);
//运行结果
hello

为什么String要不可变?(不可变的好处是什么)
1.方便实现字符串常量池,如果String可变,那么常量池就要考虑何时深拷贝字符串的问题
2.不可变对象是线程安全的
3.不可变对象更方便缓存hash code ,作为 key 时可以更高效的保存到HashMap

五.字符、字节与字符串

5.1 字符与字符串

将字符数组中的所有内容变为字符串

public String (char[] value) 

将部分字符数组中的内容变为字符串

public String (char[] value,int offset,int count) 

取得指定索引位置的字符,索引从0开始

public char charAt(int index)

将字符串变为字符数组返回

public char[] toCharArray()

5.2 字节与字符串

将字节数组变为字符串

public String (byte[] bytes) 

将部分字节数组中的内容变为字符串

public String (byte[] bytes,int offset,int length) 

将字符串以字节数组的形式返回

public byte[] getBytes()

编码转换处理

public byte[] getBytes(String charsetName) throws UnsupportedEncodingException

六.字符串常见操作

6.1 字符串比较

区分大小写的比较

public boolean equals(Object anObject)

不区分大小写的比较

public boolean equalsIgnoreCase(String anotherString)

比较两个字符串大小的关系

public int compareTo(String anotherString)

如果两个字符串相等 返回0
如果小于 返回小于0的数
如果大于 返回大于0的数

compareTo() 是一个可以区分大小写关系的方法:

字符串比较大小的规则 ,相当于判定两个字符串在一本词典的前面还是后面 ,先根据unicode的值比较第一个字符的大小,如果不分胜负,就依次比较后面的内容

6.2 字符串的查找

判断一个子字符是否存在

public boolean contains(CharSequence s)

从开始查找指定字符串的位置,查到了返回位置的开始索引,没查到返回-1

public int indexOf(String str)

从指定位置开始查找子字符串的位置

public int indexOf(String str,int fromIndex)

从后向前查找子字符串的位置

public int lastIndexOf(String str)

从指定位置从后向前查找

public int lastIndexOf(String str,int fromIndex)

判断是否以指定字符串开头

public boolean startsWith(String prefix)

从指定位置开始判断是否以指定字符串开头

public boolean startsWith(String prefix,int toffset )

判断是否以指定字符串结尾

public boolean endsWith(String suffix)

6.3 字符串替换

替换所有的指定内容

public String replaceAll(String regex,String replacement)

替换首个内容

public String replaceFirst(String regex,String replacement)

6.4 字符串拆分

将字符串全部拆分

public String[] split(String regex)

将字符串部分拆分,该数组长度就是limit极限

public String[] split(String regex,int limit)
  • 做字符串拆分时,一定要注意有些特殊字符作为分隔符可能无法正确拆分,需要加上转义
  • 字符"|","*","+“都要加上转义字符,前面加上”"
  • 而如果是"",那么就要写成"\"
  • 如果一个字符串中有多个分隔符,可以用"|"作为连字符

6.5 字符串截取

从指定索引截取到结尾

public String substring(int beginIndex)

截取部分内容

public String substring(int beginIndex,int endIndex)
  • 截取部分内容,区间是前闭后开

6.6 其他操作方法

去掉字符串中的左右空格,保留中间空格

public String trim()

字符串转大写

public String toUpperCase()

字符串转小写

public String toLowerCase()

字符串入池操作

public native String intern()

字符串连接,等同于+,不入池

public String concat(String str)

取得字符串长度

public int length()

判断是否为空字符串,不是null,而是长度为0

public boolean isEmpty()

七. StringBuffer和StringBuilder

StringStringbuffer最大的区别就在于String的内容无法修改,而StringBuffer的内容可以修改
String中用+连接字符串 而StringBuffer中需要更改为append()方法
注意StringStringBuffer不能直接转化.如果需要转换 可以采用

  • String变为StringBuffer:利用StringBuffer的构造方法或者append()方法
  • StringBuffer变为String:调用toString()方法
    StringBuffer还有一些方法:
    1.字符串反转:
public synchronized StringBuffer reverse()

2.删除指定位置的数据

public synchronized StringBuffer delect(int start,int end)

3.插入数据

public synchronized StringBuffer insert(int offset,各种数据类型 b)

String、StringBuffer、StringBuilder的区别:

  • String的内容不可修改,Stringbuffer和StringBuilder的内容都可以修改
  • StringBuffer、StringBuilder大部分功能是相似的
  • StringBuffer采用同步处理,属于线程安全操作,而Stringbuilder采用异步处理,属于线程不安全操作
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值