String对象作为 所有代码语言
(JavaScript、C#、JAVA、C++、VB、Pyhon ... )
中最基础的一个常用的代码对象,你有去好好了解过它吗?如果没有的话那今天我就带大家好好来了解一下。 (~ ̄▽ ̄)~ 废话不多说,我们一起来看看吧,走起!【我这里以JAVA为例】
String对象是 Java 中使用最频繁的对象之一,所以 Java 公司也在不断的对String对象的实现进行优化,以便提升String对象的性能,看下面这张图,一起了解一下String对象的优化过程。
1. 在 Java6 以及之前的版本中
String对象是对 char 数组进行了封装实现的对象,主要有四个成员变量:char 数组、偏移量 offset、字符数量 count、哈希值 hash。
String对象是通过 offset 和 count 两个属性来定位 char[] 数组,获取字符串。这么做可以高效、快速地共享数组对象,同时节省内存空间,但这种方式很有可能会导致内存泄漏。
2. 从 Java7 版本开始到 Java8 版本
从 Java7 版本开始,Java 对String类做了一些改变。String类中不再有 offset 和 count 两个变量了。这样的好处是String对象占用的内存稍微少了些,同时 String.substring 方法也不再共享 char[],从而解决了使用该方法可能导致的内存泄漏问题。
3. 从 Java9 版本开始
将 char[] 数组改为了 byte[] 数组,为什么需要这样做呢?我们知道 char 是两个字节,如果用来存一个字节的字符有点浪费,为了节约空间,Java 公司就改成了一个字节的byte来存储字符串。这样在存储一个字节的字符是就避免了浪费。
在 Java9 维护了一个新的属性 coder,它是编码格式的标识,在计算字符串长度或者调用 indexOf() 函数时,需要根据这个字段,判断如何计算字符串长度。coder 属性默认有 0 和 1 两个值, 0 代表Latin-1(单字节编码),1 代表 UTF-16 编码。如果 String判断字符串只包含了 Latin-1,则 coder 属性值为 0 ,反之则为 1。
1、String对象用于保存字符串,也就是一组字符序列。
2、字符串常量对象是用双引号括起来的字符序列。
3、字符串的字符使用Unicode字符编码,一个字符(不区分字母还是汉字)占两个字节。
4、String类较常用构造器:
String s1 = new String();
String s2 = new String(String original);
String s3 = new String(char[] a);
String s4 = new String(char[] a, int startIndex, int count);
5、String类继承:
5.1、实现了接口 Serializable【String可以串行化:可以在网络传输】
5.2、实现了接口 Comparable【String对象可以比较大小】
6、String是final类,不能被其他的类继承。
7、String有属性,private final char value[]; 用于存放字符串内容。
8、一定要注意:value是一个final类型,不可以修改。即value不能指向新的地址,但是单个字符内容是可以变化。
两种方式
方式一:直接使用双引号得到字符串对象
//方式一:直接使用双引号得到字符串对象
String name = "我爱你中国!";
方式二:使用String构造类
1.public String():创建一个空白字符串对象,不含有任何内容 (几乎不用)
// 1.public String():创建一个空白字符串对象,不含有任何内容 (几乎不用)
String s = new String();
2.public String(String):根据传入的字符串内容,来创建字符串对象(几乎不用)
// 2.public String(String):根据传入的字符串内容,来创建字符串对象(几乎不用)
String s2 = new String("我是中国人"); //灰色表示可有可无
3.public String(char[] c):根据字符数组的内容,来创建字符串对象
// 3.public String(char[] c):根据字符数组的内容,来创建字符串对象
char[] chars = {'a' , 'b' , '中' , '国'};
String s3 = new String(chars);
System.out.println(s3);
4.public String(byte[] b):根据字节数组的内容,来创建字符串对象
// 4.public String(byte[] b):根据字节数组的内容,来创建字符串对象
byte[] bytes = {97, 98, 99, 65, 66, 67};
String s4 = new String(bytes);
System.out.println(s4);
区别小结
:
区别一:以 “” 方式给出的字符串对象,在字符串常量池中存储,而且相同内容只会在其中存储一份。
区别二:通过构造器new对象,每new一次都会产生一个新对象,放在堆内存中。
方法 | 描述 |
---|---|
charAt | 返回在指定位置的字符。 |
charCodeAt | 返回在指定的位置的字符的 Unicode 编码。 |
concat | 连接两个或更多字符串,并返回新的字符串。 |
endsWith | 判断当前字符串是否是以指定的子字符串结尾的(区分大小写)。 |
fromCharCode | 将 Unicode 编码转为字符。 |
indexOf | 返回某个指定的字符串值在字符串中首次出现的位置。 |
includes | 查找字符串中是否包含指定的子字符串。 |
lastIndexOf | 从后向前搜索字符串,并从起始位置(0)开始计算返回字符串最后出现的位置。 |
match | 查找找到一个或多个正则表达式的匹配。 |
repeat | 复制字符串指定次数,并将它们连接在一起返回。 |
replace | 在字符串中查找匹配的子串,并替换与正则表达式匹配的子串。 |
replaceAll | 在字符串中查找匹配的子串,并替换与正则表达式匹配的所有子串。 |
search | 查找与正则表达式相匹配的值。 |
slice | 提取字符串的片断,并在新的字符串中返回被提取的部分。 |
split | 把字符串分割为字符串数组。 |
startsWith | 查看字符串是否以指定的子字符串开头。 |
substr | 从起始索引号提取字符串中指定数目的字符。 |
substring | 提取字符串中两个指定的索引号之间的字符。 |
toLowerCase | 把字符串转换为小写。 |
toUpperCase | 把字符串转换为大写。 |
trim | 去除字符串两边的空白。 |
toLocaleLowerCase | 根据本地主机的语言环境把字符串转换为小写。 |
toLocaleUpperCase | 根据本地主机的语言环境把字符串转换为大写。 |
valueOf | 返回某个字符串对象的原始值。 |
toString | 返回一个字符串。 |
String
类是保存字符串常量的。每次更新都需要重新开辟空间,效率较低,因此 java 设计者提供了StringBuilder和StringBuffer
来增强 String 的功能,并提高效率。
StringBuilder和StringBuffer
都 继 承 于AbstractStringBuilder
。
java.lang.StringBuffer
代表可变的字符序列,可以对字符串内容进行增删。
许多方法与String相同,但是StringBuffer是可变长度的,StringBuffer是一个容器。
1、StringBuffer是一个final类,不能被继承。
2、实现了Serializable接口,可以保存到文件,或网络传输;
3、继承了抽象类AbstractStringBuilder;
4、AbstractStringBuilder中有属性char[] value,不是final,该value数组存放字符串内容,因此存放在堆中;
1、一个可变的字符序列。此类提供一个与StringBuffer兼容的API,但不保证同步(StringBuilder不是线程安全)。该类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候 。如果可能,建议优先采用该类,因为在大多数实现中,它比StringBuffer要快。
2、在StringBuilder上的主要操作是append和insert方法,可重载这些方法,以接受任意类型的数据。
1、String保存的是字符串常量,里面的值不能更改,每次String类的更新实际上就是更改地址,效率较低。private final char value[];
2、StringBuffer保存的是字符串常量,里面的值可以更改,每次StringBuffer的更新实际上可以更新内容,不能更新地址,效率较高。char[] value;这个放在堆中。
三种类型的区别
StringBuilder和StringBuffer非常类似,均代表可变的字符序列,而且方法也不一样。
1、String:不可变字符序列,效率低,但是复用率高。
2、StringBuffer:可变字符序列、效率较高(增删)、线程安全。
3、StringBuilder:可变字符序列、效率最高、线程不安全。
String、StringBuffer和StringBuilder的 使用原则:
1、如果字符串存在大量的修改操作,一般使用StringBuilder或StringBuffer。
2、如果字符串存在大量的修改操作,并在单线程的情况,使用StringBuilder。
3、如果字符串存在大量的修改操作,并在多线程的情况,使用StringBuffer。
4、如果我们字符串很少修改,被多个对象引用,使用String,比如配置信息等。