文章目录
- String对象的构造
- String类的一些常用方法
- 求字符串的长度
- 字符串判空
- 字符串对象的比较
- 字符串对象的查找
- 字符串对象的转化
- 字符串对象的截取
- 字符串对象的替换
- 字符串对象的拆分
- 字符串对象的大小写转换
- 常用方法总结
- StringBuilder与StringBuffer
- 字符串为什么不可变
- String StingBuilder 与 StringBuffer的区别
String对象的构造
C语言中我们提到过字符串的概念,而C语言中并没有字符串类型,但是在Java中为我们提供了字符串类型String
,String
是引用类型,所以他并不存储字符串本身。我们通过调试来看看一个String
类型的内存结构。
如图我们构造了一个String
类型的对象string
,我们通过画图来说明一下string
的内存结构:
字符串构造有三种方法:
1、直接赋值
2、使用new String
构造对象
3、使用字符数组构造
String类的一些常用方法
求字符串的长度
int length();
计算字符串的长度。
字符串判空
boolean isEmpty();
如果字符串长度为0,就返回true,否则返回false。
字符串对象的比较
在基本类型的比较时,我们经常使用==
进行比较,但String
是引用类型使用==
比较的是对象的地址,并不是字符串对象里面value
数组中的值。要想进行值比较我们需要使用boolean equals()
。
在字符串比较中还有一个方法int compareTo(String string)
int compareTo(String string)
的返回值:
1、如果出现不等字符,直接返回这两个字符的大小插值
2、如果长度较小的字符串比完了,前面的字符都相同,那么返回两个字符串长度的差值
int compareTolgnoreCase(String string)
可以在比较时忽略字符串的大小写。
字符串对象的查找
Char charAt(int i)
找到i位置上的字符。
这样我们就可以通过循环去遍历我们的字符串了:
我们还可以在字符串中寻找一个字符第一次出现的位置int index(String str,int fromIndex)
:
我们还可以从前往后找int lastindex(String str,int fromIndex)
:
字符串对象的转化
字符串还可以进行转化,我们可以把字符串与数值进行转化String.valueOf()
,还可以将数值转化为字符串。
字符串对象的截取
我们还可以对字符串进行截取,可以指定截取的位置和长度:String substring(int beginIndex,int endIndex);
字符串对象的替换
String replaceAll(String regex,String replacement);
我们还可以对字符串中的字符统一进行替换:
字符串对象的拆分
使用String[] split(String regex,int limit);
可以对字符串进行拆分。
字符串对象的大小写转换
字符串还有一些其他的常用的方法,例如使用String trim();
去掉字符串中的左右空格,保留中间空格。String toUpperCase();
字符串转大写,String toLowerCase();
字符串转小写。
常用方法总结
以上我们就给大家介绍并演示了String
常用方法的用法,下面我们来通过一个表格来汇总一下这些方法。
方法 | 作用 |
---|---|
int length() | 计算字符串的长度 |
boolean isEmpth() | 判断字符串是否为空 |
boolean equals() | 比较字符串的大小 |
int compareTo() | 比较字符串大小,不同输出字符差值,相同输出0,最短长度相同输出长度差值。 |
char charAt(int index) | 查找字符串index位置上的字符 |
int indexOf(int ch,int fromIndex) | 从fromIndex开始查找第一次出现ch的位置,没有返回-1 |
String replaceAll(String regex,String replacement) | 替换所有的指定内容 |
String replaceFirst(String regex,String replacement) | 替换第一个出现的指定内容 |
String[] split(Stirng regex , int limit) | 将字符串以regex为分隔,拆分成limit组 |
String substring(int beginIndex,int endIndex) | 截取部分内容 |
String trim() | 去掉字符串中的左右空格,保留中间空格 |
String toUpperCase() | 字符串大写转换 |
String toLowerCase() | 字符串小写转换 |
StringBuilder与StringBuffer
字符串为什么不可变
字符串不可变?那类似下面这样的代码难道不是改变了string的值嘛?
String string = new String("abc");
string = "abcd";
我们通过调试来看一下,是否改变了字符串。
上图说明了,我们在改变字符串时都是创建了一个新对象,改变的都是新字符串对象的值,为什么会这样呢?我们ctrl+ 鼠标左键
点击String
查看他的源码。
从他的源码中我们知道了,String
类中的value[]
成员是被private final
修饰的,因为在类外无法访问到private
修饰的成员变量,所以我们无法改变String
类中存储字符的value[]
成员,所以我们说字符串无法改变。有很多人说字符串无法改变是因为value[]
被final
修饰了,其实不是,因为final
修饰value[]
表示String
类中的value[]
无法指向其他字符数组,但是其中的值是可以改变的。
String StingBuilder 与 StringBuffer的区别
上面我们说明了字符串不可变的原因,那么现在来看这样一个代码:
public static void main(String[] args) {
String string = new String("abcd");
string += "efg";
System.out.println(string);
}
我们通过观察底层的代码运行逻辑发现,短短三行的代码在底层实现起来很复杂,我们还看到StringBuilder.append()
,这些都是什么呢?让我来讲解一下
我们发现这样实现字符串的增加我们在底层实现时需要多创建两个对象一个StringBuilder
一个String
,这样一定很费时间的,那么有没有省时间的方法呢?当然有,既然我们修改字符串时需要重新创建StringBuild
对象,那么我们可不可以直接创建StringBuilder
对象呢?
我们看都是同样的需求运行的效率大不相同,原因是什么呢?
这样我们就总结出了原因:原因是StringBuilder StringBuffer
在修改字符串时并没有创建新的对象,所以效率变高了。而StringBuilder
和Stringbuffer
效率不一样的原因是StringBuffer
比StringBuilder
多了一个锁的概念,是在我们多线程中使用的,而频繁的开锁和关锁会耗费资源。
经过刚才的讲解现在我们总结一下 String StingBuilder 与 StringBuffer
的区别了:
1、
String
是不可变的,而StringBuilder StringBuffer
是可变的
2、StringBuffer
采用同步处理,属于线程安全操作,而StringBuiler
未采用同步处理,属于不安全操作,但二者功能基本相同。