目录
字符串
从概念上讲,Java 字符串就是 Unicode 字符串序列。
子串
substring(a,b); 截取包含 a 不包含 b 且 b - a 可得出字符串的长度。
String 类的 substring 方法可以从一个较大的字符串提取出一个子串。例如:
String e = ""; // an empty string
String greeting = "Hello";
拼接
Java 语言允许用 + 号连接(拼接)两个字符串,当将一个字符串与另一个非字符串的值进行拼接时,后者会转换成字符串(任何一个 Java 对象都可以转换成字符串)
String expletive = "Expletive";
String PG13 = "deleted";
String message = expletive + PG13;
// 字符串与数值拼接:
int age = 13;
String rating = "PG" + age; // "PG13"
如果需要把多个字符串放在一起,用一个界定符分隔,可以使用静态 join 方法:
join(分隔符,分隔数据);
String all = String.join(" / ", "S", "M", "L", "XL");
// all is the string "S / M / L / XL"
repeat 方法可以重复字符串:
String repeated = "Java".repeat(3); // repeated is "JavaJavaJava"
字符串不可变
String 类没有提供任何方法来修改字符串中的某个字符,因此 Java 文档中将 String 类对象称为是不可变的(immutable)。如果要修改可以先提取想要保留的字符串,再与希望替换的字符拼接:
// 将 Hello 改为 Help! :
String greeting = "Hello";
greeting = greeting.substring(0, 3) + "p!";
检测字符串是否相等
可以使用 equals 方法检测了两个字符串是否相等;要检测两个字符串是否相等,而不区分大小写,可以使用 equalsIgnoreCase 方法。
// 表达式中的 s 和 t 既可以是字符串变量,也可以是字符串字面量
s.equals(t);
String greeting = "Hello";
"Hello".equals(greeting); // 字面量
// 比较字符串且不区分大小写
"Hello".equalsIgnoreCase("hello");
注意:千万不要使用 == 运算符检测两个字符串是否相等!这个运算符只能够确定两个字符串是否存在同一个位置上。
相关知识链接:== 和 equals 的区别
空串与 Null 串
空串 " " 是长度为 0 的字符串(串长度为0,内容为空)。可以调用以下代码检查一个字符串是否为空:
if (str.length() == 0);
// or
if (str.equals(""));
null 表示目前没有任何对象与该变量关联。要检查一个字符串是否为 null ,可以使用以下代码:
if (str == null)
// 有时候要检查一个字符串既不是 null 也不是空串,这种情况下可以使用:
if (str != null && str.length() != 0)
// 首先要检查 str 不为 null
注意:如果一个 null 值上调用方法,会出现错误。
码点与代码单元(暂不理解)
码点(code point)是指与一个编码表中的某个字符对应的代码值。
在基本多语言平面中,每个字符用 16 位表示,通常称为代码单元(code unit)
Java字符串是一个 char 值序列。char 数据类型是采用 UTF-16 编码表示 Unicode 码点的一个代码单元。最常用的 Unicode 字符可以用一个代码单元表示,而辅助字符需要一对代码单元表示。
length 方法将采用 UTF-16 编码表示给定字符串所需要的代码单元个数。例如:
String greeting = "Hello";
int n = greeting.length(); // is 5
String API
查阅 Java 核心技术 卷Ⅰ 第 49 页
阅读联机 API 文档
构建字符串
如果需要许多小字符串来构建一个字符串,可以采用以下步骤。首先,构建一个空的字符串构建器:
StringBuilder builder = new StringBuilder();
// 当每次需要添加另外一部分时,就调用 append 方法。
builder.append(ch); // appends a single character
builder.append(str); // appends a string
// 字符串构建完成时,调用 to String 方法。你会得到一个 String 对象,其中包含了构建器中的字符序列
String completedString = builder.toString();
![](https://img-blog.csdnimg.cn/direct/6e7d865693dd491c967666e84eef67d1.png)
文本块
文本块格式以 """ 开始,后面是一个换行符,并以另一个 """ 结尾 ,文本块可以直接将SQL 或 HTML这些代码粘贴到一对三重引号之间。
// 开始的后面一定要换行
String greeting = """
Hello
World
""";
// 相对应的字符串字面量:
"Hello\nWorld\n"
// 如果不想要最后的 \n ,可以将结束的三引号紧贴在单词后面
// 插入 HTML 代码
String html = """
<div class="Warning">
Beware of those who say "Hello" to the world
</div>
""";
// 可以调整结束 """ 改变左边距缩进
转义问题:一般不用对引号转义。只有三种情况下需要对引号转义:
- 文本块以一个引号结尾
- 文本块中包含三个或更多引号组成的一个序列
- 反斜线都需要转义
常规字符串中的所有的转义序列在文本块中也有同样的作用,有一个转义序列只能在文本块中使用。行尾的 \ 会把这一行与下一行连接起来:
"""
Hello, my name is Hal. \
Please enter your name: """;
// 等同于:
"Hello, my name is Hal. Please enter your name: "
文本块会对行结束符进行标准化,删除末尾的空白符,并把 Windows 的行结束符(\r\n)改为简单的换行符(\n)。
警告:要当心缩进文本块的公共前缀中混用制表符和空格的情况。不小心漏掉一个空格很容易得到一个缩进错误的字符串
提示:如果一个文本块中包含非Java代码,实际上最好沿左边界放置。这样可以与Java代码区分开,而且可以为长代码流出更多空间。
输入与输出
读取输入
import java.util.*;
/**
* This program demonstrates console input.
*
* @author Cay Horstmann
* @version 1.10 2004-02-10
*/
public class InputTest {
public static void main(String[] args) {
// 首先需要构造一个与“标准输入流” System.in 关联的 Scanner 对象
Scanner in = new Scanner(System.in);
// nextLine 读取一行输入,可以接受空格
System.out.print("What is your name? ");
String name = in.nextLine();
// nextInt 用来读取一个整数
System.out.print("How old are you? ");
int age = in.nextInt();
// display output on console
System.out.println("Hello, " + name + ". Next year, you'll be " + (age +
1));
}
}
常用API
格式化输出
// 可以有多个参数,沿用 C 语言库中的约定
System.out.printf("Hello, %s. Next year, you'll be %d", name, age);
// 每一个以 % 字符开头的格式说明符都替换为相应的参数
转换说明的结构:
A 0标志
设定了 0 标志之后,如果数值的前面有空余位,则用 0 补齐数(如果省略了 0 标志,则会用空白补齐位数)。
B 最小字段宽度
也就是至少要显示出的字符位数。不设定该位数或者显示数值的实际位数超过它的时候,会根据数值显示出必要的位数。
C 精度
指定显示的最小位数,如果不指定,则整数的时候默认为 1,浮点数的时候默认为 6。
D 转换字符 注释:可以使用 s 转换字符格式化任意的对象。如果一个任意对象实现了 Formattable 接口,会调用这个对象的 formatTo 方法。否则,会调用 toString 方法将这个对象转换为一个字符串。toString 方法将在第 5 章讨论,第 6 章将介绍接口。
除此之位,还可以指定控制格式化输出外观的各种标志。例如:
System.out.printf("%,.2f", 10000.0 / 3.0); // 3,333.33
// 可以使用多个标志,例如:
// "%,(.2f" 会使用分组分隔符,并将负数包围在括号内。
System.out.printf("%,(.2f", -10000.0 / 3.0); // (3,333.33)
printf 标志:
可以使用静态的 String.format 方法创建一个格式化的字符串,而不是打印输出:
String message = String.format("Hello, %s. Next year, you'll be %d", name, age +
1);
相关知识链接:print printf println 的区别
文件输入与输出
要想读取一个文件,需要构造一个 Scanner 对象:
Scanner in = new Scanner(Path.of("myfile.txt"), StandardCharsets.UTF_8);
如果文件名中包含反斜线符号,记住要在每个反斜线之前再加一个额外的反斜线转义:"C:\\mydirectory\\myfile.txt"。
警告:可以提供一个字符串参数来构造一个 Scanner,但是这个 Scanner 会把字符串解释为数据,而不是文件名。例如,如果调用:
Scanner in = new Scanner("myfile.txt"); // ERROR?
这个 Scanner 会将参数看作是包含 10 个字符的数据。这可能不是我们的原意。
要想写入文件,需要构造一个 PrintWriter 对象。在构造器中,需要提供文件名和字符编码:
PrintWriter out = new PrintWriter("myfile.txt", StandardCharsets.UTF_8);
如果文件不存在,则创建该文件。可以像输出到 System.out 一样使用 print、println 以及 printf 命令。
如果用一个不存在的文件构造一个 Scanner,或者用一个无法创建的文件名构造一个 PrintWriter,就会产生异常。Java 编译器认为这写异常比 “被零除” 异常更严重。你已经知道有可能出现 “输入/输出” 异常。为此,要用一个 throws 子句标记 main 方法,如下所示:
public static void main(String[] args) throws IOException
{
Scanner in = new Scanner(Path.of("myfile.txt"), StandardCharsets.UTF_8);
. . .
}
常用 API: