Java字符串(String)

    |     2015年3月30日   |   Java 语法基础   |     0 条评论   |    1362

从表面上看,字符串就是双引号之间的数据,例如「极客之家」、「https://ai.zhousir.top」。写起来像 int、float 一样方便,但它其实是 java.lang.String 类的对象。

把 String 用明白,关键就两件事:怎么声明,以及为什么「改一个字符串」其实是在得到一个新对象。

一、怎么声明一个字符串

最常见的写法是字面量。因为 String 太常用,Java 为它提供了简化语法:

String stringName = "string content";
String url = "https://ai.zhousir.top";
String webName = "极客之家";

按标准的面向对象写法,应当是:

String stringName = new String("string content");
String url = new String("https://ai.zhousir.top");

之所以提供简化语法,不只是图省事。new String("abc") 实际上会涉及两个对象:一个是常量池里的 "abc",一个是 new 在堆上新申请的 String。字面量写法直接复用常量池,少一次浪费。

写法 发生了什么 什么时候用
字面量 “abc” 优先走字符串常量池,相同字面量可共用 日常声明,默认用这个
new String(“abc”) 常量池一份,堆上再 new 一份 几乎不需要,理解即可

二、用 + 拼接

字符串可以用 + 连接。基本类型和字符串做 +,一般也会自动转成字符串:

public class Demo {
    public static void main(String[] args) {
        String stuName = "小明";
        int stuAge = 17;
        float stuScore = 92.5f;

        String info = stuName + "的年龄是 " + stuAge + ",成绩是 " + stuScore;
        System.out.println(info);
    }
}

运行结果:

小明的年龄是 17,成绩是 92.5

三、不可变:看起来像修改,其实是换新对象

String 和数组有一个共同点:初始化之后,长度不变,内容也不变。你以为在改它,其实是在产生一个新字符串。

String str = "Hello ";
str += "World!";

看起来像接龙,在 str 后面接上「World!」,得到「Hello World!」。实际过程是:先有「Hello 」占着一块内存;字符串一旦初始化,这块空间的长度就是固定的,没法原地追加。要变,只能放弃原来的对象,重新申请能放下「Hello World!」的空间,再把新内容放进去。变量 str 只是改去指向这个新对象。

看起来像 实际发生了什么
str += “World!” 创建新 String,str 改指向新对象
replace(…) 返回新字符串,原串原封不动
循环里反复用 + 拼接 每次都 new,对象多、也慢

循环里大量拼接时,更合适的工具是 StringBuilder,不要用 String 一次次 +。

四、常用方法速查

String 对象有很多方法,下面几个最常用。无论字母、数字还是汉字,length() 里每个字符的长度都是 1。

方法 作用 注意
length() 返回字符串长度 汉字、字母、数字都按 1 个字符计
charAt(i) 按索引取字符 第一个字符索引是 0
contains(s) 是否包含某个子串 返回 true / false
replace(old, new) 替换所有指定子串 不改原串,返回新串
split(sep) 按分隔符切成数组 结果是 String[]

1)length()

返回字符串的长度:

String str1 = "新华苑";
String str2 = "scxh";
System.out.println("The length of str1 is " + str1.length());
System.out.println("The length of str2 is " + str2.length());

输出结果:

The length of str1 is 3
The length of str2 is 4

2)charAt()

按索引取出指定字符。Java 规定:第一个字符的索引是 0,第二个是 1,依次类推。

String str = "123456789";
System.out.println(str.charAt(0) + "    " + str.charAt(5) + "    " + str.charAt(8));

输出结果:

1    6    9

3)contains()

检测字符串是否包含某个子串:

String str = "weixueyuan";
System.out.println(str.contains("yuan"));
System.out.println(str.contains("abc"));

输出结果:

true
false

4)replace()

替换字符串中所有指定的子串。replace() 不会改变原来的字符串,而是生成一个新的字符串:

String str1 = "The url of weixueyuan is www.warmtel.com!";
String str2 = str1.replace("warmtel", "新华苑");
System.out.println(str1);
System.out.println(str2);

输出结果:

The url of weixueyuan is www.warmtel.com!
The url of weixueyuan is www.新华苑.com!

str1 打印出来仍是原文,只有 str2 里的 warmtel 被换成了「新华苑」。

5)split()

以指定字符串作为分隔符,把当前字符串切成数组:

import java.util.*;

public class Demo {
    public static void main(String[] args) {
        String str = "wei_xue_yuan_is_good";
        String[] strArr = str.split("_");
        System.out.println(Arrays.toString(strArr));
    }
}

运行结果:

[wei, xue, yuan, is, good]

以上只列举了几个常用方法,更多方法和详细解释请参考 JDK 的 API 文档。

五、参考与收尾

  • 日常声明用字面量,不必 new String。
  • String 不可变:+、+=、replace 都是得到新对象。
  • 循环里大量拼接,改用 StringBuilder。

一句话总结:String 是不可变的类。字面量走常量池,+ / replace / += 看起来像在改,其实都在得到新对象。把这件事记住,常用 API 用起来才不会踩坑。

转载请注明来源:Java字符串(String)
本文链接地址:https://ai.zhousir.top/?p=54

上一篇:

下一篇:

回复 取消