From 21ba10d296784435a677b6e18eb32349236341fb Mon Sep 17 00:00:00 2001 From: 1326670425 <1326670425@qq.com> Date: Sun, 10 Nov 2019 12:36:38 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E7=AC=AC=E4=BA=8C=E5=8D=81=E7=AB=A0=20?= =?UTF-8?q?=E6=B3=9B=E5=9E=8B=20=20=E7=BF=BB=E8=AF=91=E6=9B=B4=E6=96=B0=20?= =?UTF-8?q?=E8=A1=A5=E5=81=BF=E6=93=A6=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/book/20-Generics.md | 526 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 526 insertions(+) diff --git a/docs/book/20-Generics.md b/docs/book/20-Generics.md index da1a4d3..938b5f9 100644 --- a/docs/book/20-Generics.md +++ b/docs/book/20-Generics.md @@ -1233,6 +1233,532 @@ public class Store extends ArrayList { ## 补偿擦除 +因为擦除,我们将失去执行泛型代码中某些操作的能力。无法在运行时知道确切类型: + +```java +// generics/Erased.java +// {WillNotCompile} + +public class Erased { + private final int SIZE = 100; + + public void f(Object arg) { + + // error: illegal generic type for instanceof + if (arg instanceof T) { + } + + // error: unexpected type + T var = new T(); + + // error: generic array creation + T[] array = new T[SIZE]; + + // warning: [unchecked] unchecked cast + T[] array = (T[]) new Object[SIZE]; + + } +} +``` + +有时,我们可以对这些问题进行编程,但是有时必须通过引入类型标签来补偿擦除。这意味着为所需的类型显式传递一个 **Class** 对象,以在类型表达式中使用它。 + +例如,由于删除了类型信息,因此在上一个程序中尝试使用 **instanceof** 将会失败。类型标签可以使用动态 `isInstance()` : + +```java +// generics/ClassTypeCapture.java + +class Building { +} + +class House extends Building { +} + +public class ClassTypeCapture { + Class kind; + + public ClassTypeCapture(Class kind) { + this.kind = kind; + } + + public boolean f(Object arg) { + return kind.isInstance(arg); + } + + public static void main(String[] args) { + ClassTypeCapture ctt1 = + new ClassTypeCapture<>(Building.class); + System.out.println(ctt1.f(new Building())); + System.out.println(ctt1.f(new House())); + ClassTypeCapture ctt2 = + new ClassTypeCapture<>(House.class); + System.out.println(ctt2.f(new Building())); + System.out.println(ctt2.f(new House())); + } +} +/* Output: +true +true +false +true +*/ +``` + +编译器来保证类型标签与泛型参数相匹配。 + + +### 创建类型的实例 + +试图在 **Erased.java** 中 `new T()` 是行不通的,部分原因是由于擦除,部分原因是编译器无法验证 **T** 是否具有默认(无参)构造函数。但是在 C++ 中,此操作自然,直接且安全(在编译时检查): + +```C++ +// generics/InstantiateGenericType.cpp +// C++, not Java! + +template class Foo { + T x; // Create a field of type T + T* y; // Pointer to T +public: + // Initialize the pointer: + Foo() { y = new T(); } +}; + +class Bar {}; + +int main() { + Foo fb; + Foo fi; // ... and it works with primitives +} +``` + +Java 中的解决方案是传入一个工厂对象,并使用该对象创建新实例。方便的工厂对象只是 **Class** 对象,因此,如果使用类型标记,则可以使用 `newInstance()` 创建该类型的新对象: + +```java +// generics/InstantiateGenericType.java + +import java.util.function.Supplier; + +class ClassAsFactory implements Supplier { + Class kind; + + ClassAsFactory(Class kind) { + this.kind = kind; + } + + @Override + public T get() { + try { + return kind.newInstance(); + } catch (InstantiationException | + IllegalAccessException e) { + throw new RuntimeException(e); + } + } +} + +class Employee { + @Override + public String toString() { + return "Employee"; + } +} + +public class InstantiateGenericType { + public static void main(String[] args) { + ClassAsFactory fe = + new ClassAsFactory<>(Employee.class); + System.out.println(fe.get()); + ClassAsFactory fi = + new ClassAsFactory<>(Integer.class); + try { + System.out.println(fi.get()); + } catch (Exception e) { + System.out.println(e.getMessage()); + } + } +} +/* Output: +Employee +java.lang.InstantiationException: java.lang.Integer +*/ +``` + +这样可以编译,但对于 `ClassAsFactory \` 会失败,这是因为 **Integer** 没有无参构造函数。由于错误不是在编译时捕获的,因此语言创建者不赞成这种方法。他们建议使用显式工厂(**Supplier**)并约束类型,以便只有实现该工厂的类可以这样创建对象。这是创建工厂的两种不同方法: + +```java +// generics/FactoryConstraint.java + +import onjava.Suppliers; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +class IntegerFactory implements Supplier { + private int i = 0; + + @Override + public Integer get() { + return ++i; + } +} + +class Widget { + private int id; + + Widget(int n) { + id = n; + } + + @Override + public String toString() { + return "Widget " + id; + } + + public static + class Factory implements Supplier { + private int i = 0; + + @Override + public Widget get() { + return new Widget(++i); + } + } +} + +class Fudge { + private static int count = 1; + private int n = count++; + + @Override + public String toString() { + return "Fudge " + n; + } +} + +class Foo2 { + private List x = new ArrayList<>(); + + Foo2(Supplier factory) { + Suppliers.fill(x, factory, 5); + } + + @Override + public String toString() { + return x.toString(); + } +} + +public class FactoryConstraint { + public static void main(String[] args) { + System.out.println( + new Foo2<>(new IntegerFactory())); + System.out.println( + new Foo2<>(new Widget.Factory())); + System.out.println( + new Foo2<>(Fudge::new)); + } +} +/* Output: +[1, 2, 3, 4, 5] +[Widget 1, Widget 2, Widget 3, Widget 4, Widget 5] +[Fudge 1, Fudge 2, Fudge 3, Fudge 4, Fudge 5] +*/ +``` + +**IntegerFactory** 本身就是通过实现 `Supplier\` 的工厂。 **Widget** 包含一个内部类,它是一个工厂。还要注意,**Fudge** 并没有做任何类似于工厂的操作,并且传递 `Fudge::new` 仍然会产生工厂行为,因为编译器将对函数方法 `::new` 的调用转换为对 `get()` 的调用。 + +另一种方法是模板方法设计模式。在以下示例中,`create()` 是模板方法,在子类中被重写以生成该类型的对象: + +```java +// generics/CreatorGeneric.java + +abstract class GenericWithCreate { + final T element; + + GenericWithCreate() { + element = create(); + } + + abstract T create(); +} + +class X { +} + +class XCreator extends GenericWithCreate { + @Override + X create() { + return new X(); + } + + void f() { + System.out.println( + element.getClass().getSimpleName()); + } +} + +public class CreatorGeneric { + public static void main(String[] args) { + XCreator xc = new XCreator(); + xc.f(); + } +} +/* Output: +X +*/ +``` + +**GenericWithCreate** 包含 `element` 字段,并通过无参构造函数强制其初始化,该构造函数又调用抽象的 `create()` 方法。这种创建方式可以在子类中定义,同时建立 **T** 的类型。 + + +### 泛型数组 + +正如在 **Erased.java** 中所看到的,我们无法创建泛型数组。通用解决方案是在试图创建泛型数组的时候使用 **ArrayList** : + +```java +// generics/ListOfGenerics.java + +import java.util.ArrayList; +import java.util.List; + +public class ListOfGenerics { + private List array = new ArrayList<>(); + + public void add(T item) { + array.add(item); + } + + public T get(int index) { + return array.get(index); + } +} +``` + +这样做可以获得数组的行为,并且还具有泛型提供的编译时类型安全性。 + +有时,仍然会创建泛型类型的数组(例如, **ArrayList** 在内部使用数组)。可以通过使编译器满意的方式定义对数组的通用引用: + +```java +// generics/ArrayOfGenericReference.java + +class Generic { +} + +public class ArrayOfGenericReference { + static Generic[] gia; +} +``` + +编译器接受此操作而不产生警告。但是我们永远无法创建具有该确切类型(包括类型参数)的数组,因此有点令人困惑。由于所有数组,无论它们持有什么类型,都具有相同的结构(每个数组插槽的大小和数组布局),因此似乎可以创建一个 **Object** 数组并将其转换为所需的数组类型。实际上,这确实可以编译,但是会产生 **ClassCastException** : + +```java +// generics/ArrayOfGeneric.java + +public class ArrayOfGeneric { + static final int SIZE = 100; + static Generic[] gia; + + @SuppressWarnings("unchecked") + public static void main(String[] args) { + try { + gia = (Generic[]) new Object[SIZE]; + } catch (ClassCastException e) { + System.out.println(e.getMessage()); + } + // Runtime type is the raw (erased) type: + gia = (Generic[]) new Generic[SIZE]; + System.out.println(gia.getClass().getSimpleName()); + gia[0] = new Generic<>(); + //- gia[1] = new Object(); // Compile-time error + // Discovers type mismatch at compile time: + //- gia[2] = new Generic(); + } +} +/* Output: +[Ljava.lang.Object; cannot be cast to [LGeneric; +Generic[] +*/ +``` + +问题在于数组会跟踪其实际类型,而该类型是在创建数组时建立的。因此,即使 `gia` 被强制转换为 `Generic\[]` ,该信息也仅在编译时存在(并且没有 **@SuppressWarnings** 注解,将会收到有关该强制转换的警告)。在运行时,它仍然是一个对象数组,这会引起问题。成功创建泛型类型的数组的唯一方法是创建一个已擦除类型的新数组,并将其强制转换。 + +让我们看一个更复杂的示例。考虑一个包装数组的简单泛型包装器: + +```java +// generics/GenericArray.java + +public class GenericArray { + private T[] array; + + @SuppressWarnings("unchecked") + public GenericArray(int sz) { + array = (T[]) new Object[sz]; + } + + public void put(int index, T item) { + array[index] = item; + } + + public T get(int index) { + return array[index]; + } + + // Method that exposes the underlying representation: + public T[] rep() { + return array; + } + + public static void main(String[] args) { + GenericArray gai = new GenericArray<>(10); + try { + Integer[] ia = gai.rep(); + } catch (ClassCastException e) { + System.out.println(e.getMessage()); + } + // This is OK: + Object[] oa = gai.rep(); + } +} +/* Output: +[Ljava.lang.Object; cannot be cast to +[Ljava.lang.Integer; +*/ +``` + +和以前一样,我们不能说 `T[] array = new T[sz]` ,所以我们创建了一个 **Object** 数组并将其强制转换。 + +`rep()` 方法返回一个 `T[]` ,在主方法中它应该是 `gai` 的 `Integer[]` ,但是如果调用它并尝试将结果转换为 `Integer[]` 引用,则会得到 **ClassCastException** ,这再次是因为实际的运行时类型为 `Object[]` 。 + +如果再注释掉 **@SuppressWarnings** 注解后编译 **GenericArray.java** ,则编译器会产生警告: + +```java +GenericArray.java uses unchecked or unsafe operations. +Recompile with -Xlint:unchecked for details. +``` + +在这里,我们收到了一个警告,我们认为这是有关强制转换的。 + +但是要真正确定,请使用 `-Xlint:unchecked` 进行编译: + +```java +GenericArray.java:7: warning: [unchecked] unchecked cast array = (T[])new Object[sz]; ^ required: T[] found: Object[] where T is a type-variable: T extends Object declared in class GenericArray 1 warning +``` + +确实是在抱怨那个强制转换。由于警告会变成噪音,因此,一旦我们确认预期会出现特定警告,我们可以做的最好的办法就是使用 **@SuppressWarnings** 将其关闭。这样,当警告确实出现时,我们将进行实际调查。 + +由于擦除,数组的运行时类型只能是 `Object[]` 。 如果我们立即将其转换为 `T[]` ,则在编译时会丢失数组的实际类型,并且编译器可能会错过一些潜在的错误检查。因此,最好在集合中使用 `Object[]` ,并在使用数组元素时向 **T** 添加强制类型转换。让我们来看看在 **GenericArray.java** 示例中会是怎么样的: + +```java +// generics/GenericArray2.java + +public class GenericArray2 { + private Object[] array; + + public GenericArray2(int sz) { + array = new Object[sz]; + } + + public void put(int index, T item) { + array[index] = item; + } + + @SuppressWarnings("unchecked") + public T get(int index) { + return (T) array[index]; + } + + @SuppressWarnings("unchecked") + public T[] rep() { + return (T[]) array; // Unchecked cast + } + + public static void main(String[] args) { + GenericArray2 gai = + new GenericArray2<>(10); + for (int i = 0; i < 10; i++) + gai.put(i, i); + for (int i = 0; i < 10; i++) + System.out.print(gai.get(i) + " "); + System.out.println(); + try { + Integer[] ia = gai.rep(); + } catch (Exception e) { + System.out.println(e); + } + } +} +/* Output: +0 1 2 3 4 5 6 7 8 9 +java.lang.ClassCastException: [Ljava.lang.Object; +cannot be cast to [Ljava.lang.Integer; +*/ +``` + +最初,看起来并没有太大不同,只是转换的位置移动了。没有 **@SuppressWarnings** 注解,仍然会收到“unchecked”警告。但是,内部表示现在是 `Object[]` 而不是 `T[]` 。 调用 `get()` 时,它将对象强制转换为 **T** ,实际上这是正确的类型,因此很安全。但是,如果调用 `rep()` ,它将再次尝试将 `Object[]` 强制转换为 `T[]` ,但仍然不正确,并在编译时生成警告,并在运行时生成异常。因此,无法破坏基础数组的类型,该基础数组只能是 `Object[]` 。在内部将数组视为 `Object[]` 而不是 `T[]` 的优点是,我们不太可能会忘记数组的运行时类型并意外地引入了bug,尽管大多数(也许是全部)此类错误会在运行时被迅速检测到。 + +对于新代码,请传入类型标记。在这种情况下,**GenericArray** 如下所示: + +```java +// generics/GenericArrayWithTypeToken.java + +import java.lang.reflect.Array; + +public class GenericArrayWithTypeToken { + private T[] array; + + @SuppressWarnings("unchecked") + public GenericArrayWithTypeToken(Class type, int sz) { + array = (T[]) Array.newInstance(type, sz); + } + + public void put(int index, T item) { + array[index] = item; + } + + public T get(int index) { + return array[index]; + } + + // Expose the underlying representation: + public T[] rep() { + return array; + } + + public static void main(String[] args) { + GenericArrayWithTypeToken gai = + new GenericArrayWithTypeToken<>( + Integer.class, 10); + // This now works: + Integer[] ia = gai.rep(); + } +} +``` + +类型标记 **Class\** 被传递到构造函数中以从擦除中恢复,因此尽管必须使用 **@SuppressWarnings** 关闭来自强制类型转换的警告,但我们仍可以创建所需的实际数组类型。一旦获得了实际的类型,就可以返回它并产生所需的结果,如在主方法中看到的那样。数组的运行时类型是确切的类型 `T[]` 。 + +不幸的是,如果查看 Java 标准库中的源代码,你会发现到处都有从 **Object** 数组到参数化类型的转换。例如,这是**ArrayList** 中,复制一个 **Collection** 的构造函数,这里为了简化,去除了源码中对此不重要的代码: + +```java +public ArrayList(Collection c) { + size = c.size(); + elementData = (E[])new Object[size]; + c.toArray(elementData); +} +``` + +如果你浏览 **ArrayList.java** 的代码,将会发现很多此类强制转换。当我们编译它时会发生什么? + +```java +Note: ArrayList.java uses unchecked or unsafe operations +Note: Recompile with -Xlint:unchecked for details. +``` + +果然,标准库会产生很多警告。如果你使用过 C 语言,尤其是使用 ANSI C 之前的语言,你会记住警告的特殊效果:发现警告后,可以忽略它们。因此,除非程序员必须对其进行处理,否则最好不要从编译器发出任何类型的消息。 + +Neal Gafter(Java 5的主要开发人员之一)在他的博客中[^2]指出,他在重写 Java 库时很懒惰,我们不应该做他所做的事情。Neal 还指出,他在不破坏现有接口的情况下无法修复某些 Java 库代码。因此,即使某些习惯用法出现在 Java 库源代码中,也不一定是正确的做法。当查看库代码时,我们不能假设这是您在自己的代码中必须要遵循的示例。 + +请注意,在 Java 文献中推荐使用类型标记技术,例如 Gilad Bracha 的论文《Generics in the Java Programming Language》[^3],他指出:“例如,这种用法已广泛用于新的 API 中以处理注解。” 我发现此技术在人们对于舒适度的看法方面存在一些不一致之处;有些人强烈喜欢本章前面介绍的工厂方法。 ## 边界 From b36d9897de441f91beacb509d831405cbfcb6260 Mon Sep 17 00:00:00 2001 From: xiangflight Date: Thu, 7 Nov 2019 21:23:51 +0800 Subject: [PATCH 2/4] =?UTF-8?q?revision[18]=20=E7=BB=93=E6=9D=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/book/16-Validating-Your-Code.md | 2 +- docs/book/17-Files.md | 4 +- docs/book/18-Strings.md | 777 ++++++++++++++------------- 3 files changed, 393 insertions(+), 390 deletions(-) diff --git a/docs/book/16-Validating-Your-Code.md b/docs/book/16-Validating-Your-Code.md index f143721..4630605 100644 --- a/docs/book/16-Validating-Your-Code.md +++ b/docs/book/16-Validating-Your-Code.md @@ -28,7 +28,7 @@ C 风格的语言,尤其是 C++,通常会认为性能比安全更重要。 #### JUnit -最初的 JUnit 发布于 2000 年,大概是基于 Java 1.0,因此不能使用 Java 的反射工具。因此,用旧的 JUnit 编写单元测试是一项相当繁忙和冗长的工作。我发现这个设计令人不爽,并编写了自己的单元测试框架作为[注解](./Annotations.md)一章的示例。这个框架走向了另一个极端,“尝试最简单可行的方法”(极限编程中的一个关键短语)。从那之后,JUnit 通过反射和注解得到了极大的改进,大大简化了编写单元测试代码的过程。在 Java8 中,他们甚至增加了对 lambdas 表达式的支持。本书使用当时最新的 Junit5 版本 +最初的 JUnit 发布于 2000 年,大概是基于 Java 1.0,因此不能使用 Java 的反射工具。因此,用旧的 JUnit 编写单元测试是一项相当繁忙和冗长的工作。我发现这个设计令人不爽,并编写了自己的单元测试框架作为 [注解](./Annotations.md) 一章的示例。这个框架走向了另一个极端,“尝试最简单可行的方法”(极限编程中的一个关键短语)。从那之后,JUnit 通过反射和注解得到了极大的改进,大大简化了编写单元测试代码的过程。在 Java8 中,他们甚至增加了对 lambdas 表达式的支持。本书使用当时最新的 Junit5 版本 在 JUnit 最简单的使用中,使用 **@Test** 注解标记表示测试的每个方法。JUnit 将这些方法标识为单独的测试,并一次设置和运行一个测试,采取措施避免测试之间的副作用。 diff --git a/docs/book/17-Files.md b/docs/book/17-Files.md index 4106bcc..c92cb29 100644 --- a/docs/book/17-Files.md +++ b/docs/book/17-Files.md @@ -5,7 +5,7 @@ # 第十七章 文件 >在丑陋的 Java I/O 编程方式诞生多年以后,Java终于简化了文件读写的基本操作。 -这种"困难方式"的全部细节都在 [Appendix: I/O Streams](.\Appendix-IO-Streams.md)。如果你读过这个部分,就会认同 Java 设计者毫不在意他们的使用者的体验这一观念。打开并读取文件对于大多数编程语言来是非常常用的,由于 I/O 糟糕的设计以至于 +这种"困难方式"的全部细节都在 [Appendix: I/O Streams](./Appendix-IO-Streams.md)。如果你读过这个部分,就会认同 Java 设计者毫不在意他们的使用者的体验这一观念。打开并读取文件对于大多数编程语言来是非常常用的,由于 I/O 糟糕的设计以至于 很少有人能够在不依赖其他参考代码的情况下完成打开文件的操作。 好像 Java 设计者终于意识到了 Java 使用者多年来的痛苦,在 Java7 中对此引入了巨大的改进。这些新元素被放在 **java.nio.file** 包下面,过去人们通常把 **nio** 中的 **n** 理解为 **new** 即新的 **io**,现在更应该当成是 **non-blocking** 非阻塞 **io**(**io**就是*input/output输入/输出*)。**java.nio.file** 库终于将 Java 文件操作带到与其他编程语言相同的水平。最重要的是 Java8 新增的 streams 与文件结合使得文件操作编程变得更加优雅。我们将看一下文件操作的两个基本组件: @@ -514,7 +514,7 @@ sun.nio.fs.WindowsFileSystemProvider@6d06d69c File Attribute Views: [owner, dos, acl, basic, user] */ ``` -一个**FileSystem** 对象也能生成 **WatchService** 和 **PathMatcher** 对象,将会在接下来两章中详细讲解。 +一个 **FileSystem** 对象也能生成 **WatchService** 和 **PathMatcher** 对象,将会在接下来两章中详细讲解。 diff --git a/docs/book/18-Strings.md b/docs/book/18-Strings.md index f831902..4282fc0 100644 --- a/docs/book/18-Strings.md +++ b/docs/book/18-Strings.md @@ -10,7 +10,7 @@ ## 字符串的不可变 -`String` 对象是不可变的。查看 JDK 文档你就会发现,`String` 类中每一个看起来会修改 `String` 值的方法,实际上都是创建了一个全新的 `String` 对象,以包含修改后的字符串内容。而最初的`String` 对象则丝毫未动。 +`String` 对象是不可变的。查看 JDK 文档你就会发现,`String` 类中每一个看起来会修改 `String` 值的方法,实际上都是创建了一个全新的 `String` 对象,以包含修改后的字符串内容。而最初的 `String` 对象则丝毫未动。 看看下面的代码: ```java @@ -57,10 +57,10 @@ String x = Immutable.upcase(s); // strings/Concatenation.java public class Concatenation { - public static void main(String[] args) { - String mango = "mango"; - String s = "abc" + mango + "def" + 47; - System.out.println(s); + public static void main(String[] args) { + String mango = "mango"; + String s = "abc" + mango + "def" + 47; + System.out.println(s); } } /* Output: @@ -71,7 +71,7 @@ abcmangodef47 这种方式当然是可行的,但是为了生成最终的 `String` 对象,会产生一大堆需要垃圾回收的中间对象。我猜想,Java 设计者一开始就是这么做的(这也是软件设计中的一个教训:除非你用代码将系统实现,并让它运行起来,否则你无法真正了解它会有什么问题),然后他们发现其性能相当糟糕。 -想看看以上代码到底是如何工作的吗?可以用JDK自带的 `javap` 工具来反编译以上代码。命令如下: +想看看以上代码到底是如何工作的吗?可以用 JDK 自带的 `javap` 工具来反编译以上代码。命令如下: ```java javap -c Concatenation ``` @@ -158,9 +158,9 @@ public java.lang.String implicit(java.lang.String[]); 51: aload_2 52: areturn ``` -注意从第 16 行到第 48 行构成了一个循环体。第 16 行:对堆栈中的操作数进行“大于或等于的整数比较运算”,循环结束时跳转到第 51 行。第 48 行:重新回到循环体的起始位置(第 12 行)。注意:`StringBuilder` 是在循环内构造的,这意味着每进行一次循环,会创建一个新的`StringBuilder`对象。 +注意从第 16 行到第 48 行构成了一个循环体。第 16 行:对堆栈中的操作数进行“大于或等于的整数比较运算”,循环结束时跳转到第 51 行。第 48 行:重新回到循环体的起始位置(第 12 行)。注意:`StringBuilder` 是在循环内构造的,这意味着每进行一次循环,会创建一个新的 `StringBuilder` 对象。 -下面是`explicit()`方法对应的字节码: +下面是 `explicit()` 方法对应的字节码: ```x86asm public java.lang.String explicit(java.lang.String[]); 0: new #3 // StringBuilder @@ -411,15 +411,15 @@ Terry The Turtle is at (3,3) 所有的 `tommy` 都将输出到 `System.out`,而所有的 `terry` 则都输出到 `System.out` 的一个别名中。`Formatter` 的重载构造器支持输出到多个路径,不过最常用的还是 `PrintStream()`(如上例)、`OutputStream` 和 `File`。你可以在 [附录:流式 I/O](././Appendix-IO-Streams.md) 中了解更多信息。 ### 格式化修饰符 -在插入数据时,如果想要优化空格与对齐,你需要更精细复杂的格式修饰符。以下是其抽象语法: +在插入数据时,如果想要优化空格与对齐,你需要更精细复杂的格式修饰符。以下是其通用语法: ```java %[argument_index$][flags][width][.precision]conversion ``` -最常见的应用是控制一个字段的最小长度,这可以通过指定*width*来实现。`Formatter`对象通过在必要时添加空格,来确保一个字段至少达到设定长度。默认情况下,数据是右对齐的,不过可以通过使用`-`标志来改变对齐方向。 +最常见的应用是控制一个字段的最小长度,这可以通过指定 *width* 来实现。`Formatter `对象通过在必要时添加空格,来确保一个字段至少达到设定长度。默认情况下,数据是右对齐的,不过可以通过使用 `-` 标志来改变对齐方向。 -与*width*相对的是*precision*,用于指定最大长度。*width*可以应用于各种类型的数据转换,并且其行为方式都一样。*precision*则不然,不是所有的类型都能使用*precision*,而且,应用于不同类型的数据转换时,*precision*的意义也不同。在将*precision*应用于`String`时,它表示打印`string`时输出字符的最大数量。而在将*precision*应用于浮点数时,它表示小数部分要显示出来的位数(默认是6位小数),如果小数位数过多则舍入,太少则在尾部补零。由于整数没有小数部分,所以*precision*无法应用于整数,如果你对整数应用*precision*,则会触发异常。 +与 *width* 相对的是 *precision*,用于指定最大长度。*width* 可以应用于各种类型的数据转换,并且其行为方式都一样。*precision* 则不然,当应用于不同类型的数据转换时,*precision* 的意义也不同。在将 *precision* 应用于 `String` 时,它表示打印 `string` 时输出字符的最大数量。而在将 *precision* 应用于浮点数时,它表示小数部分要显示出来的位数(默认是 6 位小数),如果小数位数过多则舍入,太少则在尾部补零。由于整数没有小数部分,所以 *precision* 无法应用于整数,如果你对整数应用 *precision*,则会触发异常。 -下面的程序应用格式修饰符来打印一个购物收据。这是*Builder*设计模式的一个简单实现,即先创建一个初始对象,然后逐渐添加新东西,最后调用`build()`方法完成构建: +下面的程序应用格式修饰符来打印一个购物收据。这是 *Builder* 设计模式的一个简单实现,即先创建一个初始对象,然后逐渐添加新东西,最后调用 `build()` 方法完成构建: ```java // strings/ReceiptBuilder.java import java.util.*; @@ -467,10 +467,10 @@ Tax 2.80 Total 49.39 */ ``` -通过传入一个`StringBuilder`对象到`Formatter`的构造器,我们指定了一个容器来构建目标`String`。你也可以通过不同的构造器参数,把结果输出到标准输出,甚至是一个文件里。 +通过传入一个 `StringBuilder` 对象到 `Formatter` 的构造器,我们指定了一个容器来构建目标 `String`。你也可以通过不同的构造器参数,把结果输出到标准输出,甚至是一个文件里。 -正如你所见,通过相当简洁的语法,`Formatter`提供了对空格与对齐的强大控制能力。在该程序中,为了恰当地控制间隔,格式化字符串被重复利用了多遍。 -### `Formatter`转换 +正如你所见,通过相当简洁的语法,`Formatter ` 提供了对空格与对齐的强大控制能力。在该程序中,为了恰当地控制间隔,格式化字符串被重复利用了多遍。 +### `Formatter` 转换 下面的表格展示了最常用的类型转换: | 类型 | 含义 | @@ -602,11 +602,11 @@ h: 4d5 ``` 被注释的代码表示,针对相应类型的变量,这些转换是无效的。如果执行这些转换,则会触发异常。 -注意,程序中的每个变量都用到了`b`转换。虽然它对各种类型都是合法的,但其行为却不一定与你想象的一致。对于`boolean`基本类型或`Boolean`对象,其转换结果是对应的`true`或`false`。但是,对其他类型的参数,只要该参数不为`null`,其转换结果永远都是`true`。即使是数字0,转换结果依然为`true`,而这在其他语言中(包括C),往往转换为`false`。所以,将`b`应用于非布尔类型的对象时请格外小心。 +注意,程序中的每个变量都用到了 `b` 转换。虽然它对各种类型都是合法的,但其行为却不一定与你想象的一致。对于 `boolean` 基本类型或 `Boolean` 对象,其转换结果是对应的 `true` 或 `false`。但是,对其他类型的参数,只要该参数不为 `null`,其转换结果永远都是 `true`。即使是数字 0,转换结果依然为 `true`,而这在其他语言中(包括C),往往转换为 `false`。所以,将 `b` 应用于非布尔类型的对象时请格外小心。 -还有许多不常用的类型转换与格式修饰符选项,你可以在JDK文档中的`Formatter`类部分找到它们。 +还有许多不常用的类型转换与格式修饰符选项,你可以在 JDK 文档中的 `Formatter` 类部分找到它们。 ### `String.format()` -Java SE5也参考了C中的`sprintf()`方法,以生成格式化的`String`对象。`String.format()`是一个`static`方法,它接受与`Formatter.format()`方法一样的参数,但返回一个`String`对象。当你只需使用一次`format()`方法的时候,`String.format()`用起来很方便。例如: +Java SE5 也参考了 C 中的 `sprintf()` 方法,以生成格式化的 `String` 对象。`String.format()` 是一个 `static` 方法,它接受与 `Formatter.format()` 方法一样的参数,但返回一个 `String` 对象。当你只需使用一次 `format()` 方法的时候,`String.format()` 用起来很方便。例如: ```java // strings/DatabaseException.java @@ -629,9 +629,9 @@ Output: DatabaseException: (t3, q7) Write failed */ ``` -其实在`String.format()`内部,它也是创建了一个`Formatter`对象,然后将你传入的参数转给`Formatter`。不过,与其自己做这些事情,不如使用便捷的`String.format()`方法,何况这样的代码更清晰易读。 +其实在 `String.format()` 内部,它也是创建了一个 `Formatter` 对象,然后将你传入的参数转给 `Formatter`。不过,与其自己做这些事情,不如使用便捷的 `String.format()` 方法,何况这样的代码更清晰易读。 #### 一个十六进制转储(dump)工具 -在第二个例子中,我们把二进制文件转换为十六进制格式。下面的小工具使用了`String.format()`方法,以可读的十六进制格式将字节数组打印出来: +在第二个例子中,我们把二进制文件转换为十六进制格式。下面的小工具使用了 `String.format()` 方法,以可读的十六进制格式将字节数组打印出来: ```java // strings/Hex.java // {java onjava.Hex} @@ -641,27 +641,27 @@ import java.nio.file.*; public class Hex { public static String format(byte[] data) { - StringBuilder result = new StringBuilder(); - int n = 0; - for(byte b : data) { - if(n % 16 == 0) - result.append(String.format("%05X: ", n)); - result.append(String.format("%02X ", b)); - n++; - if(n % 16 == 0) result.append("\n"); - } - result.append("\n"); - return result.toString(); + StringBuilder result = new StringBuilder(); + int n = 0; + for(byte b : data) { + if(n % 16 == 0) + result.append(String.format("%05X: ", n)); + result.append(String.format("%02X ", b)); + n++; + if(n % 16 == 0) result.append("\n"); + } + result.append("\n"); + return result.toString(); } public static void main(String[] args) throws Exception { - if(args.length == 0) - // Test by displaying this class file: - System.out.println(format( - Files.readAllBytes(Paths.get( - "build/classes/main/onjava/Hex.class")))); - else - System.out.println(format( - Files.readAllBytes(Paths.get(args[0])))); + if(args.length == 0) + // Test by displaying this class file: + System.out.println(format( + Files.readAllBytes(Paths.get( + "build/classes/main/onjava/Hex.class")))); + else + System.out.println(format( + Files.readAllBytes(Paths.get(args[0])))); } } /* Output: (First 6 Lines) @@ -674,36 +674,36 @@ public class Hex { ... */ ``` -为了打开及读入二进制文件,我们用到了另一个工具`Files.readAllBytes()`,这已经在[Files章节](#)介绍过了。这里的`readAllBytes()`方法将整个文件以`byte`数组的形式返回。 - +为了打开及读入二进制文件,我们用到了另一个工具 `Files.readAllBytes()`,这已经在 [Files章节](./17-Files.md) 介绍过了。这里的 `readAllBytes()` 方法将整个文件以 `byte` 数组的形式返回。 -## 正则表达式 -很久之前,*正则表达式*就已经整合到标准Unix工具集之中,例如sed、awk和程序语言之中了,如Python和Perl(有些人认为正是正则表达式促成了Perl的成功)。而在Java中,字符串操作还主要集中于`String`、`StringBuffer`和`StringTokenizer`类。与正则表达式相比较,它们只能提供相当简单的功能。 -正则表达式是一种强大而灵活的文本处理工具。使用正则表达式,我们能够以编程的方式,构造复杂的文本模式,并对输入`String`进行搜索。一旦找到了匹配这些模式的部分,你就能随心所欲地对它们进行处理。初学正则表达式时,其语法是一个难点,但它确实是一种简洁、动态的语言。正则表达式提供了一种完全通用的方式,能够解决各种`String`处理相关的问题:匹配、选择、编辑以及验证。 +## 正则表达式 +很久之前,*正则表达式*就已经整合到标准 Unix 工具集之中,例如 sed、awk 和程序语言之中了,如 Python 和Perl(有些人认为正是正则表达式促成了 Perl 的成功)。而在 Java 中,字符串操作还主要集中于`String`、`StringBuffer` 和 `StringTokenizer` 类。与正则表达式相比较,它们只能提供相当简单的功能。 + +正则表达式是一种强大而灵活的文本处理工具。使用正则表达式,我们能够以编程的方式,构造复杂的文本模式,并对输入 `String` 进行搜索。一旦找到了匹配这些模式的部分,你就能随心所欲地对它们进行处理。初学正则表达式时,其语法是一个难点,但它确实是一种简洁、动态的语言。正则表达式提供了一种完全通用的方式,能够解决各种 `String` 处理相关的问题:匹配、选择、编辑以及验证。 ### 基础 一般来说,正则表达式就是以某种方式来描述字符串,因此你可以说:“如果一个字符串含有这些东西,那么它就是我正在找的东西。”例如,要找一个数字,它可能有一个负号在最前面,那你就写一个负号加上一个问号,就像这样: ```java -? ``` -要描述一个整数,你可以说它有一位或多位阿拉伯数字。在正则表达式中,用`\d`表示一位数字。如果在其他语言中使用过正则表达式,那你可能就能发现Java对反斜线\的不同处理方式。在其他语言中,`\\`表示“我想要在正则表达式中插入一个普通的(字面上的)反斜线,请不要给它任何特殊的意义。”而在Java中,`\\`的意思是“我要插入一个正则表达式的反斜线,所以其后的字符具有特殊的意义。”例如,如果你想表示一位数字,那么正则表达式因该是`\\d`。如果你想插入一个普通的反斜线,应该这样写`\\\`。不过换行符和制表符之类的东西只需要使用单反斜线:`\n\t`。 [^2] +要描述一个整数,你可以说它有一位或多位阿拉伯数字。在正则表达式中,用 `\d` 表示一位数字。如果在其他语言中使用过正则表达式,那你可能就能发现 Java 对反斜线 \ 的不同处理方式。在其他语言中,`\\` 表示“我想要在正则表达式中插入一个普通的(字面上的)反斜线,请不要给它任何特殊的意义。”而在Java中,`\\` 的意思是“我要插入一个正则表达式的反斜线,所以其后的字符具有特殊的意义。”例如,如果你想表示一位数字,那么正则表达式应该是 `\\d`。如果你想插入一个普通的反斜线,应该这样写 `\\\`。不过换行符和制表符之类的东西只需要使用单反斜线:`\n\t`。 [^2] -要表示“一个或多个之前的表达式”,应该使用`+`。所以,如果要表示“可能有一个负号,后面跟着一位或多位数字”,可以这样: +要表示“一个或多个之前的表达式”,应该使用 `+`。所以,如果要表示“可能有一个负号,后面跟着一位或多位数字”,可以这样: ```java -?\\d+ ``` -应用正则表达式最简单的途径,就是利用`String`类内建的功能。例如,你可以检查一个`String`是否匹配如上所述的正则表达式: +应用正则表达式最简单的途径,就是利用 `String` 类内建的功能。例如,你可以检查一个 `String` 是否匹配如上所述的正则表达式: ```java // strings/IntegerMatch.java public class IntegerMatch { - public static void main(String[] args) { - System.out.println("-1234".matches("-?\\d+")); - System.out.println("5678".matches("-?\\d+")); - System.out.println("+911".matches("-?\\d+")); - System.out.println("+911".matches("(|-\\+)?\\d+")); - } + public static void main(String[] args) { + System.out.println("-1234".matches("-?\\d+")); + System.out.println("5678".matches("-?\\d+")); + System.out.println("+911".matches("-?\\d+")); + System.out.println("+911".matches("(-|\\+)?\\d+")); + } } /* Output: true @@ -712,30 +712,31 @@ false true */ ``` -前两个字符串都满足对应的正则表达式,匹配成功。第三个字符串以`+`开头,这也是一个合法的符号,但与对应的正则表达式却不匹配。因此,我们的正则表达式应该描述为:“可能以一个加号或减号开头”。在正则表达式中,用括号将表达式进行分组,用竖线` | `表示或操作。也就是: +前两个字符串都满足对应的正则表达式,匹配成功。第三个字符串以 `+` 开头,这也是一个合法的符号,但与对应的正则表达式却不匹配。因此,我们的正则表达式应该描述为:“可能以一个加号或减号开头”。在正则表达式中,用括号将表达式进行分组,用竖线 ` | ` 表示或操作。也就是: ```java (-|\\+)? ``` -这个正则表达式表示字符串的起始字符可能是一个`-`或`+`,或者二者都没有(因为后面跟着`?`修饰符)。因为字符`+`在正则表达式中有特殊的意义,所以必须使用`\\`将其转义,使之成为表达式中的一个普通字符。 +这个正则表达式表示字符串的起始字符可能是一个 `-` 或 `+`,或者二者都没有(因为后面跟着 `?` 修饰符)。因为字符 `+` 在正则表达式中有特殊的意义,所以必须使用 `\\` 将其转义,使之成为表达式中的一个普通字符。 + +`String`类还自带了一个非常有用的正则表达式工具——`split()` 方法,其功能是“将字符串从正则表达式匹配的地方切开。” -`String`类还自带了一个非常有用的正则表达式工具——`split()`方法,其功能是“将字符串从正则表达式匹配的地方切开。” ```java // strings/Splitting.java import java.util.*; public class Splitting { - public static String knights = - "Then, when you have found the shrubbery, " + - "you must cut down the mightiest tree in the " + - "forest...with... a herring!"; - public static void split(String regex) { - System.out.println( - Arrays.toString(knights.split(regex))); + public static String knights = + "Then, when you have found the shrubbery, " + + "you must cut down the mightiest tree in the " + + "forest...with... a herring!"; + public static void split(String regex) { + System.out.println( + Arrays.toString(knights.split(regex))); + } + public static void main(String[] args) { + split(" "); // Doesn't have to contain regex chars + split("\\W+"); // Non-word characters + split("n\\W+"); // 'n' followed by non-words } - public static void main(String[] args) { - split(" "); // Doesn't have to contain regex chars - split("\\W+"); // Non-word characters - split("n\\W+"); // 'n' followed by non-words - } } /* Output: [Then,, when, you, have, found, the, shrubbery,, you, @@ -749,24 +750,24 @@ dow, the mightiest tree i, the forest...with... a herring!] */ ``` -首先看第一个语句,注意这里用的是普通的字符作为正则表达式,其中并不包含任何特殊字符。因此第一个`split()`只是按空格来划分字符串。 +首先看第一个语句,注意这里用的是普通的字符作为正则表达式,其中并不包含任何特殊字符。因此第一个 `split()` 只是按空格来划分字符串。 -第二个和第三个`split()`都用到了`\\W`,它的意思是一个非单词字符(如果W小写,`\\w`,则表示一个单词字符)。通过第二个例子可以看到,它将标点字符删除了。第三个`split()`表示“字母`n`后面跟着一个或多个非单词字符。”可以看到,在原始字符串中,与正则表达式匹配的部分,在最终结果中都不存在了。 +第二个和第三个 `split()` 都用到了 `\\W`,它的意思是一个非单词字符(如果 W 小写,`\\w`,则表示一个单词字符)。通过第二个例子可以看到,它将标点字符删除了。第三个 `split()` 表示“字母 `n` 后面跟着一个或多个非单词字符。”可以看到,在原始字符串中,与正则表达式匹配的部分,在最终结果中都不存在了。 -`String.split()`还有一个重载的版本,它允许你限制字符串分割的次数。 +`String.split()` 还有一个重载的版本,它允许你限制字符串分割的次数。 用正则表达式进行替换操作时,你可以只替换第一处匹配,也可以替换所有的匹配: ```java // strings/Replacing.java public class Replacing { - static String s = Splitting.knights; - public static void main(String[] args) { - System.out.println( - s.replaceFirst("f\\w+", "located")); - System.out.println( - s.replaceAll("shrubbery|tree|herring","banana")); - } + static String s = Splitting.knights; + public static void main(String[] args) { + System.out.println( + s.replaceFirst("f\\w+", "located")); + System.out.println( + s.replaceAll("shrubbery|tree|herring","banana")); + } } /* Output: Then, when you have located the shrubbery, you must cut @@ -776,13 +777,13 @@ Then, when you have found the banana, you must cut down the mightiest banana in the forest...with... a banana! */ ``` -第一个表达式要匹配的是,以字母`f`开头,后面跟一个或多个字母(注意这里的`w`是小写的)。并且只替换掉第一个匹配的部分,所以“found”被替换成“located”。 +第一个表达式要匹配的是,以字母 `f` 开头,后面跟一个或多个字母(注意这里的 `w` 是小写的)。并且只替换掉第一个匹配的部分,所以 “found” 被替换成 “located”。 第二个表达式要匹配的是三个单词中的任意一个,因为它们以竖线分割表示“或”,并且替换所有匹配的部分。 -稍后你会看到,`String`之外的正则表达式还有更强大的替换工具,例如,可以通过方法调用执行替换。而且,如果正则表达式不是只使用一次的话,非`String`对象的正则表达式明显具备更佳的性能。 +稍后你会看到,`String` 之外的正则表达式还有更强大的替换工具,例如,可以通过方法调用执行替换。而且,如果正则表达式不是只使用一次的话,非 `String` 对象的正则表达式明显具备更佳的性能。 ### 创建正则表达式 -我们首先从正则表达式可能存在的构造集中选取一个很有用的子集,以此开始学习正则表达式。正则表达式的完整构造子列表,请参考JDK文档`java.util.regex`包中的`Pattern`类。 +我们首先从正则表达式可能存在的构造集中选取一个很有用的子集,以此开始学习正则表达式。正则表达式的完整构造子列表,请参考JDK文档 `java.util.regex` 包中的 `Pattern`类。 | 表达式 | 含义 | | :---- | :---- | @@ -812,12 +813,12 @@ the mightiest banana in the forest...with... a banana! | `\w` | 词字符(`[a-zA-Z_0-9]`) | | `\W` | 非词字符(`[^\w]`) | -这里只列出了部分常用的表达式,你应该将JDK文档中`java.util.regex.Pattern`那一页加入浏览器书签中,以便在需要的时候方便查询。 +这里只列出了部分常用的表达式,你应该将JDK文档中 `java.util.regex.Pattern` 那一页加入浏览器书签中,以便在需要的时候方便查询。 | 逻辑操作符 | 含义 | | :----: | :---- | | `XY` | `Y`跟在`X`后面 | -| `X\|Y` | `X`或`Y` | +| `X|Y` | `X`或`Y` | | `(X)` | 捕获组(capturing group)。可以在表达式中用`\i`引用第i个捕获组 | 下面是不同的边界匹配符: @@ -835,14 +836,14 @@ the mightiest banana in the forest...with... a banana! // strings/Rudolph.java public class Rudolph { - public static void main(String[] args) { - for(String pattern : new String[]{ - "Rudolph", - "[rR]udolph", - "[rR][aeiou][a-z]ol.*", - "R.*" }) - System.out.println("Rudolph".matches(pattern)); - } + public static void main(String[] args) { + for(String pattern : new String[]{ + "Rudolph", + "[rR]udolph", + "[rR][aeiou][a-z]ol.*", + "R.*" }) + System.out.println("Rudolph".matches(pattern)); + } } /* Output: true @@ -862,7 +863,7 @@ true 用问号来指定,这个量词匹配满足模式所需的最少字符数。因此也被称作懒惰的、最少匹配的、非贪婪的或不贪婪的。 + **占有型**: -目前,这种类型的量词只有在Java语言中才可用(在其他语言中不可用),并且也更高级,因此我们大概不会立刻用到它。当正则表达式被应用于`String`时,它会产生相当多的状态,以便在匹配失败时可以回溯。而“占有的”量词并不保存这些中间状态,因此它们可以防止回溯。它们常常用于防止正则表达式失控,因此可以使正则表达式执行起来更高效。 +目前,这种类型的量词只有在 Java 语言中才可用(在其他语言中不可用),并且也更高级,因此我们大概不会立刻用到它。当正则表达式被应用于 `String` 时,它会产生相当多的状态,以便在匹配失败时可以回溯。而“占有的”量词并不保存这些中间状态,因此它们可以防止回溯。它们常常用于防止正则表达式失控,因此可以使正则表达式执行起来更高效。 | 贪婪型 | 勉强型 | 占有型 | 如何匹配 | | ---- | ---- | ---- | ---- | @@ -873,7 +874,7 @@ true | `X{n,}` | `X{n,}?` | `X{n,}+` | 至少`n`次`X` | | `X{n,m}` | `X{n,m}?` | `X{n,m}+` | `X`至少`n`次,但不超过`m`次 | -应该非常清楚地意识到,表达式`X`通常必须要用圆括号括起来,以便它能够按照我们期望的效果去执行。例如: +应该非常清楚地意识到,表达式 `X` 通常必须要用圆括号括起来,以便它能够按照我们期望的效果去执行。例如: ```java abc+ ``` @@ -881,20 +882,20 @@ abc+ ```java (abc)+ ``` -你会发现,在使用正则表达式时很容易混淆,因为它是一种在Java之上的新语言。 +你会发现,在使用正则表达式时很容易混淆,因为它是一种在 Java 之上的新语言。 ### `CharSequence` -接口`CharSequence`从`CharBuffer`、`String`、`StringBuffer`、`StringBuilder`类中抽象出了字符序列的一般化定义: +接口 `CharSequence` 从 `CharBuffer`、`String`、`StringBuffer`、`StringBuilder` 类中抽象出了字符序列的一般化定义: ```java interface CharSequence { - char charAt(int i); - int length(); - CharSequence subSequence(int start, int end); - String toString(); + char charAt(int i); + int length(); + CharSequence subSequence(int start, int end); + String toString(); } ``` -因此,这些类都实现了该接口。多数正则表达式操作都接受`CharSequence`类型参数。 -### `Pattern`和`Matcher` -通常,比起功能有限的`String`类,我们更愿意构造功能强大的正则表达式对象。只需导入`java.util.regex`包,然后用`static Pattern.compile()`方法来编译你的正则表达式即可。它会根据你的`String`类型的正则表达式生成一个`Pattern`对象。接下来,把你想要检索的字符串传入`Pattern`对象的`matcher()`方法。`matcher()`方法会生成一个`Matcher`对象,它有很多功能可用(可以参考`java.util.regext.Matcher`的JDK文档)。例如,它的`replaceAll()`方法能将所有匹配的部分都替换成你传入的参数。 +因此,这些类都实现了该接口。多数正则表达式操作都接受 `CharSequence` 类型参数。 +### `Pattern` 和 `Matcher` +通常,比起功能有限的 `String` 类,我们更愿意构造功能强大的正则表达式对象。只需导入 `java.util.regex`包,然后用 `static Pattern.compile()` 方法来编译你的正则表达式即可。它会根据你的 `String` 类型的正则表达式生成一个 `Pattern` 对象。接下来,把你想要检索的字符串传入 `Pattern` 对象的 `matcher()` 方法。`matcher()` 方法会生成一个 `Matcher` 对象,它有很多功能可用(可以参考 `java.util.regext.Matcher` 的 JDK 文档)。例如,它的 `replaceAll()` 方法能将所有匹配的部分都替换成你传入的参数。 作为第一个示例,下面的类可以用来测试正则表达式,看看它们能否匹配一个输入字符串。第一个控制台参数是将要用来搜索匹配的输入字符串,后面的一个或多个参数都是正则表达式,它们将被用来在输入的第一个字符串中查找匹配。在Unix/Linux上,命令行中的正则表达式必须用引号括起来。这个程序在测试正则表达式时很有用,特别是当你想验证它们是否具备你所期待的匹配功能的时候。[^3] ```java @@ -905,26 +906,26 @@ interface CharSequence { import java.util.regex.*; public class TestRegularExpression { - public static void main(String[] args) { - if(args.length < 2) { - System.out.println( - "Usage:\njava TestRegularExpression " + - "characterSequence regularExpression+"); - System.exit(0); + public static void main(String[] args) { + if(args.length < 2) { + System.out.println( + "Usage:\njava TestRegularExpression " + + "characterSequence regularExpression+"); + System.exit(0); + } + System.out.println("Input: \"" + args[0] + "\""); + for(String arg : args) { + System.out.println( + "Regular expression: \"" + arg + "\""); + Pattern p = Pattern.compile(arg); + Matcher m = p.matcher(args[0]); + while(m.find()) { + System.out.println( + "Match \"" + m.group() + "\" at positions " + + m.start() + "-" + (m.end() - 1)); + } + } } - System.out.println("Input: \"" + args[0] + "\""); - for(String arg : args) { - System.out.println( - "Regular expression: \"" + arg + "\""); - Pattern p = Pattern.compile(arg); - Matcher m = p.matcher(args[0]); - while(m.find()) { - System.out.println( - "Match \"" + m.group() + "\" at positions " + - m.start() + "-" + (m.end() - 1)); - } - } - } } /* Output: Input: "abcabcabcdefabc" @@ -942,40 +943,42 @@ Match "abc" at positions 12-14 ``` 还可以在控制台参数中加入`“(abc){2,}”`,看看执行结果。 -`Pattern`对象表示编译后的正则表达式。从这个例子可以看到,我们使用已编译的`Pattern`对象上的`matcher()`方法,加上一个输入字符串,从而共同构造了一个`Matcher`对象。同时,`Pattern`类还提供了一个`static`方法: +`Pattern` 对象表示编译后的正则表达式。从这个例子可以看到,我们使用已编译的 `Pattern` 对象上的 `matcher()` 方法,加上一个输入字符串,从而共同构造了一个 `Matcher` 对象。同时,`Pattern` 类还提供了一个`static`方法: + ```java static boolean matches(String regex, CharSequence input) ``` -该方法用以检查`regex`是否匹配整个`CharSequence`类型的`input`参数。编译后的`Pattern`对象还提供了`split()`方法,它从匹配了`regex`的地方分割输入字符串,返回分割后的子字符串`String`数组。 +该方法用以检查 `regex` 是否匹配整个 `CharSequence` 类型的 `input` 参数。编译后的 `Pattern` 对象还提供了 `split()` 方法,它从匹配了 `regex` 的地方分割输入字符串,返回分割后的子字符串 `String` 数组。 -通过调用`Pattern.matcher()`方法,并传入一个字符串参数,我们得到了一个`Matcher`对象。使用`Matcher`上的方法,我们将能够判断各种不同类型的匹配是否成功: +通过调用 `Pattern.matcher()` 方法,并传入一个字符串参数,我们得到了一个 `Matcher` 对象。使用 `Matcher` 上的方法,我们将能够判断各种不同类型的匹配是否成功: ```java boolean matches() boolean lookingAt() boolean find() boolean find(int start) ``` -其中的`matches()`方法用来判断整个输入字符串是否匹配正则表达式模式,而`lookingAt()`则用来判断该字符串(不必是整个字符串)的起始部分是否能够匹配模式。 +其中的 `matches()` 方法用来判断整个输入字符串是否匹配正则表达式模式,而 `lookingAt()` 则用来判断该字符串(不必是整个字符串)的起始部分是否能够匹配模式。 ### `find()` -`Matcher.find()`方法可用来在`CharSequence`中查找多个匹配。例如: +`Matcher.find()` 方法可用来在 `CharSequence` 中查找多个匹配。例如: + ```java // strings/Finding.java import java.util.regex.*; public class Finding { - public static void main(String[] args) { - Matcher m = Pattern.compile("\\w+") - .matcher( - "Evening is full of the linnet's wings"); - while(m.find()) - System.out.print(m.group() + " "); - System.out.println(); - int i = 0; - while(m.find(i)) { - System.out.print(m.group() + " "); - i++; - } - } + public static void main(String[] args) { + Matcher m = Pattern.compile("\\w+") + .matcher( + "Evening is full of the linnet's wings"); + while(m.find()) + System.out.print(m.group() + " "); + System.out.println(); + int i = 0; + while(m.find(i)) { + System.out.print(m.group() + " "); + i++; + } + } } /* Output: Evening is full of the linnet s wings @@ -984,18 +987,19 @@ ull ll l of of f the the he e linnet linnet innet nnet net et t s s wings wings ings ngs gs s */ ``` -模式`\\w+`将字符串划分为词。`find()`方法像迭代器那样向前遍历输入字符串。而第二个重载的`find()`接收一个整型参数,该整数表示字符串中字符的位置,并以其作为搜索的起点。从结果可以看出,后一个版本的`find()`方法能够根据其参数的值,不断重新设定搜索的起始位置。 +模式 `\\w+` 将字符串划分为词。`find()` 方法像迭代器那样向前遍历输入字符串。而第二个重载的 `find()` 接收一个整型参数,该整数表示字符串中字符的位置,并以其作为搜索的起点。从结果可以看出,后一个版本的 `find()` 方法能够根据其参数的值,不断重新设定搜索的起始位置。 ### 组(Groups) -组是用括号划分的正则表达式,可以根据组的编号来引用某个组。组号为0表示整个表达式,组号1表示被第一对括号括起来的组,以此类推。因此,下面这个表达式, +组是用括号划分的正则表达式,可以根据组的编号来引用某个组。组号为 0 表示整个表达式,组号 1 表示被第一对括号括起来的组,以此类推。因此,下面这个表达式, ```java A(B(C))D ``` -中有三个组:组0是`ABCD`,组1是`BC`,组2是`C`。 +中有三个组:组 0 是 `ABCD`,组 1 是 `BC`,组 2 是 `C`。 -`Matcher`对象提供了一系列方法,用以获取与组相关的信息: -+ `public int groupCount()` 返回该匹配器的模式中的分组数目,组0不包括在内。 -+ `public String group()` 返回前一次匹配操作(例如`find()`)的第0组(整个匹配)。 -+ `public String group(int i)` 返回前一次匹配操作期间指定的组号,如果匹配成功,但是指定的组没有匹配输入字符串的任何部分,则将返回`null`。 +`Matcher` 对象提供了一系列方法,用以获取与组相关的信息: + ++ `public int groupCount()` 返回该匹配器的模式中的分组数目,组 0 不包括在内。 ++ `public String group()` 返回前一次匹配操作(例如 `find()`)的第 0 组(整个匹配)。 ++ `public String group(int i)` 返回前一次匹配操作期间指定的组号,如果匹配成功,但是指定的组没有匹配输入字符串的任何部分,则将返回 `null`。 + `public int start(int group)` 返回在前一次匹配操作中寻找到的组的起始索引。 + `public int end(int group)` 返回在前一次匹配操作中寻找到的组的最后一个字符索引加一的值。 @@ -1005,25 +1009,25 @@ A(B(C))D import java.util.regex.*; public class Groups { - public static final String POEM = - "Twas brillig, and the slithy toves\n" + - "Did gyre and gimble in the wabe.\n" + - "All mimsy were the borogoves,\n" + - "And the mome raths outgrabe.\n\n" + - "Beware the Jabberwock, my son,\n" + - "The jaws that bite, the claws that catch.\n" + - "Beware the Jubjub bird, and shun\n" + - "The frumious Bandersnatch."; - public static void main(String[] args) { - Matcher m = Pattern.compile( - "(?m)(\\S+)\\s+((\\S+)\\s+(\\S+))$") - .matcher(POEM); - while(m.find()) { - for(int j = 0; j <= m.groupCount(); j++) - System.out.print("[" + m.group(j) + "]"); - System.out.println(); - } - } + public static final String POEM = + "Twas brillig, and the slithy toves\n" + + "Did gyre and gimble in the wabe.\n" + + "All mimsy were the borogoves,\n" + + "And the mome raths outgrabe.\n\n" + + "Beware the Jabberwock, my son,\n" + + "The jaws that bite, the claws that catch.\n" + + "Beware the Jubjub bird, and shun\n" + + "The frumious Bandersnatch."; + public static void main(String[] args) { + Matcher m = Pattern.compile( + "(?m)(\\S+)\\s+((\\S+)\\s+(\\S+))$") + .matcher(POEM); + while(m.find()) { + for(int j = 0; j <= m.groupCount(); j++) + System.out.print("[" + m.group(j) + "]"); + System.out.println(); + } + } } /* Output: [the slithy toves][the][slithy toves][slithy][toves] @@ -1039,55 +1043,58 @@ outgrabe.][raths][outgrabe.] Bandersnatch.][frumious][Bandersnatch.] */ ``` -这首诗来自于Lewis Carroll所写的*Through the Looking Glass*中的“Jabberwocky”。可以看到这个正则表达式模式有许多圆括号分组,由任意数目的非空白符(`\\S+`)及随后的任意数目的空白符(`\\s+`)所组成。目的是捕获每行的最后3个词,每行最后以`\$`结束。不过,在正常情况下是将`\$`与整个输入序列的末端相匹配。所以我们一定要显示地告知正则表达式注意输入序列中的换行符。这可以由序列开头的模式标记`(?m)`来完成(模式标记马上就会介绍)。 -### `start()`和`end()` -在匹配操作成功之后,`start()`返回先前匹配的起始位置的索引,而`end()`返回所匹配的最后字符的索引加一的值。匹配操作失败之后(或先于一个正在进行的匹配操作去尝试)调用`start()`或`end()`将会产生`IllegalStateException`。下面的示例还同时展示了`matches()`和`lookingAt()`的用法 [^4]: +这首诗来自于 Lewis Carroll 所写的 *Through the Looking Glass* 中的 “Jabberwocky”。可以看到这个正则表达式模式有许多圆括号分组,由任意数目的非空白符(`\\S+`)及随后的任意数目的空白符(`\\s+`)所组成。目的是捕获每行的最后3个词,每行最后以 `\$` 结束。不过,在正常情况下是将 `\$` 与整个输入序列的末端相匹配。所以我们一定要显式地告知正则表达式注意输入序列中的换行符。这可以由序列开头的模式标记 `(?m)` 来完成(模式标记马上就会介绍)。 +### `start()` 和 `end()` +在匹配操作成功之后,`start()` 返回先前匹配的起始位置的索引,而 `end()` 返回所匹配的最后字符的索引加一的值。匹配操作失败之后(或先于一个正在进行的匹配操作去尝试)调用 `start()` 或 `end()` 将会产生 `IllegalStateException`。下面的示例还同时展示了 `matches()` 和 `lookingAt()` 的用法 [^4]: ```java // strings/StartEnd.java import java.util.regex.*; public class StartEnd { - public static String input = - "As long as there is injustice, whenever a\n" + - "Targathian baby cries out, wherever a distress\n" + - "signal sounds among the stars " + - "... We'll be there.\n"+ - "This fine ship, and this fine crew ...\n" + - "Never give up! Never surrender!"; - private static class Display { - private boolean regexPrinted = false; - private String regex; - Display(String regex) { this.regex = regex; } - void display(String message) { - if(!regexPrinted) { - System.out.println(regex); - regexPrinted = true; - } - System.out.println(message); + public static String input = + "As long as there is injustice, whenever a\n" + + "Targathian baby cries out, wherever a distress\n" + + "signal sounds among the stars " + + "... We'll be there.\n"+ + "This fine ship, and this fine crew ...\n" + + "Never give up! Never surrender!"; + private static class Display { + private boolean regexPrinted = false; + private String regex; + Display(String regex) { this.regex = regex; } + + void display(String message) { + if(!regexPrinted) { + System.out.println(regex); + regexPrinted = true; + } + System.out.println(message); + } } - } - static void examine(String s, String regex) { - Display d = new Display(regex); - Pattern p = Pattern.compile(regex); - Matcher m = p.matcher(s); - while(m.find()) - d.display("find() '" + m.group() + - "' start = "+ m.start() + " end = " + m.end()); - if(m.lookingAt()) // No reset() necessary - d.display("lookingAt() start = " - + m.start() + " end = " + m.end()); - if(m.matches()) // No reset() necessary - d.display("matches() start = " - + m.start() + " end = " + m.end()); - } - public static void main(String[] args) { - for(String in : input.split("\n")) { - System.out.println("input : " + in); - for(String regex : new String[]{"\\w*ere\\w*", - "\\w*ever", "T\\w+", "Never.*?!"}) - examine(in, regex); - } - } + + static void examine(String s, String regex) { + Display d = new Display(regex); + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(s); + while(m.find()) + d.display("find() '" + m.group() + + "' start = "+ m.start() + " end = " + m.end()); + if(m.lookingAt()) // No reset() necessary + d.display("lookingAt() start = " + + m.start() + " end = " + m.end()); + if(m.matches()) // No reset() necessary + d.display("matches() start = " + + m.start() + " end = " + m.end()); + } + + public static void main(String[] args) { + for(String in : input.split("\n")) { + System.out.println("input : " + in); + for(String regex : new String[]{"\\w*ere\\w*", + "\\w*ever", "T\\w+", "Never.*?!"}) + examine(in, regex); + } + } } /* Output: input : As long as there is injustice, whenever a @@ -1121,13 +1128,14 @@ lookingAt() start = 0 end = 14 matches() start = 0 end = 31 */ ``` -注意,`find()`可以在输入的任意位置定位正则表达式,而`lookingAt()`和`matches()`只有在正则表达式与输入的最开始处就开始匹配时才会成功。`matches()`只有在整个输入都匹配正则表达式时才会成功,而`lookingAt()` [^5]只要输入的第一部分匹配就会成功。 -### `Pattern`标记 -`Pattern`类的`compile()`方法还有另一个版本,它接受一个标记参数,以调整匹配行为: +注意,`find()` 可以在输入的任意位置定位正则表达式,而 `lookingAt()` 和 `matches()` 只有在正则表达式与输入的最开始处就开始匹配时才会成功。`matches()` 只有在整个输入都匹配正则表达式时才会成功,而 `lookingAt()` [^5] 只要输入的第一部分匹配就会成功。 +### `Pattern` 标记 +`Pattern` 类的 `compile()` 方法还有另一个版本,它接受一个标记参数,以调整匹配行为: + ```java Pattern Pattern.compile(String regex, int flag) ``` -其中的`flag`来自以下`Pattern`类中的常量 +其中的 `flag` 来自以下 `Pattern` 类中的常量 | 编译标记 | 效果 | | ---- |---- | @@ -1139,7 +1147,7 @@ Pattern Pattern.compile(String regex, int flag) | `Pattern.UNICODE_CASE(?u)` | 当指定这个标记,并且开启`CASE_INSENSITIVE`时,大小写不敏感的匹配将按照与Unicode标准相一致的方式进行。默认情况下,大小写不敏感的匹配假定只能在US-ASCII字符集中的字符才能进行 | | `Pattern.UNIX_LINES(?d)` | 在这种模式下,在`.`、`^`和`$`的行为中,只识别行终止符`\n` | -在这些标记中,`Pattern.CASE_INSENSITIVE`、`Pattern.MULTILINE`以及`Pattern.COMMENTS`(对声明或文档有用)特别有用。请注意,你可以直接在正则表达式中使用其中的大多数标记,只需要将上表中括号括起来的字符插入到正则表达式中,你希望它起作用的位置即可。 +在这些标记中,`Pattern.CASE_INSENSITIVE`、`Pattern.MULTILINE` 以及 `Pattern.COMMENTS`(对声明或文档有用)特别有用。请注意,你可以直接在正则表达式中使用其中的大多数标记,只需要将上表中括号括起来的字符插入到正则表达式中,你希望它起作用的位置即可。 你还可以通过“或”(`|`)操作符组合多个标记的功能: ```java @@ -1147,16 +1155,16 @@ Pattern Pattern.compile(String regex, int flag) import java.util.regex.*; public class ReFlags { - public static void main(String[] args) { - Pattern p = Pattern.compile("^java", - Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - Matcher m = p.matcher( - "java has regex\nJava has regex\n" + - "JAVA has pretty good regular expressions\n" + - "Regular expressions are in Java"); - while(m.find()) - System.out.println(m.group()); - } + public static void main(String[] args) { + Pattern p = Pattern.compile("^java", + Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); + Matcher m = p.matcher( + "java has regex\nJava has regex\n" + + "JAVA has pretty good regular expressions\n" + + "Regular expressions are in Java"); + while(m.find()) + System.out.println(m.group()); + } } /* Output: java @@ -1164,9 +1172,10 @@ Java JAVA */ ``` -在这个例子中,我们创建了一个模式,它将匹配所有以“java”、“Java”和“JAVA”等开头的行,并且是在设置了多行标记的状态下,对每一行(从字符序列的第一个字符开始,至每一个行终止符)都进行匹配。注意,`group()`方法只返回已匹配的部分。 +在这个例子中,我们创建了一个模式,它将匹配所有以“java”、“Java”和“JAVA”等开头的行,并且是在设置了多行标记的状态下,对每一行(从字符序列的第一个字符开始,至每一个行终止符)都进行匹配。注意,`group()` 方法只返回已匹配的部分。 ### `split()` -`split()`方法将输入`String`断开成`String`对象数组,断开边界由正则表达式确定: +`split()`方法将输入 `String` 断开成 `String` 对象数组,断开边界由正则表达式确定: + ```java String[] split(CharSequence input) String[] split(CharSequence input, int limit) @@ -1178,28 +1187,28 @@ import java.util.regex.*; import java.util.*; public class SplitDemo { - public static void main(String[] args) { - String input = - "This!!unusual use!!of exclamation!!points"; - System.out.println(Arrays.toString( - Pattern.compile("!!").split(input))); - // Only do the first three: - System.out.println(Arrays.toString( - Pattern.compile("!!").split(input, 3))); - } + public static void main(String[] args) { + String input = + "This!!unusual use!!of exclamation!!points"; + System.out.println(Arrays.toString( + Pattern.compile("!!").split(input))); + // Only do the first three: + System.out.println(Arrays.toString( + Pattern.compile("!!").split(input, 3))); + } } /* Output: [This, unusual use, of exclamation, points] [This, unusual use, of exclamation!!points] */ ``` -第二种形式的`split()`方法可以限制将输入分割成字符串的数量。 +第二种形式的 `split()` 方法可以限制将输入分割成字符串的数量。 ### 替换操作 正则表达式在进行文本替换时特别方便,它提供了许多方法: -+ `replaceFirst(String replacement)` 以参数字符串`replacement`替换掉第一个匹配成功的部分。 -+ `replaceAll(String replacement)` 以参数字符串`replacement`替换所有匹配成功的部分。 -+ `appendReplacement(StringBuffer sbuf, String replacement)` 执行渐进式的替换,而不是像`replaceFirst()`和`replaceAll()`那样只替换第一个匹配或全部匹配。这是一个非常重要的方法。它允许你调用其他方法来生成或处理`replacement`(`replaceFirst()`和`replaceAll()`则只能使用一个固定的字符串),使你能够以编程的方式将目标分割成组,从而具备更强大的替换功能。 -+ `appendTail(StringBuffer sbuf)` 在执行了一次或多次`appendReplacement()`之后,调用此方法可以将输入字符串余下的部分复制到`sbuf`中。 ++ `replaceFirst(String replacement)` 以参数字符串 `replacement` 替换掉第一个匹配成功的部分。 ++ `replaceAll(String replacement)` 以参数字符串 `replacement` 替换所有匹配成功的部分。 ++ `appendReplacement(StringBuffer sbuf, String replacement)` 执行渐进式的替换,而不是像 `replaceFirst()` 和 `replaceAll()` 那样只替换第一个匹配或全部匹配。这是一个非常重要的方法。它允许你调用其他方法来生成或处理 `replacement`(`replaceFirst()` 和 `replaceAll()` 则只能使用一个固定的字符串),使你能够以编程的方式将目标分割成组,从而具备更强大的替换功能。 ++ `appendTail(StringBuffer sbuf)` 在执行了一次或多次 `appendReplacement()` 之后,调用此方法可以将输入字符串余下的部分复制到 `sbuf` 中。 下面的程序演示了如何使用这些替换方法。开头部分注释掉的文本,就是正则表达式要处理的输入字符串: ```java @@ -1215,34 +1224,33 @@ import java.util.stream.*; extracted block. !*/ public class TheReplacements { - public static void main(String[] args) throws Exception { - String s = Files.lines( - Paths.get("TheReplacements.java")) - .collect(Collectors.joining("\n")); - // Match specially commented block of text above: - Matcher mInput = Pattern.compile( - "/\\*!(.*)!\\*/", Pattern.DOTALL).matcher(s); - if(mInput.find()) - s = mInput.group(1); // Captured by parentheses - // Replace two or more spaces with a single space: - s = s.replaceAll(" {2,}", " "); - // Replace 1+ spaces at the beginning of each - // line with no spaces. Must enable MULTILINE mode: - s = s.replaceAll("(?m)^ +", ""); - System.out.println(s); - s = s.replaceFirst("[aeiou]", "(VOWEL1)"); - StringBuffer sbuf = new StringBuffer(); - Pattern p = Pattern.compile("[aeiou]"); - Matcher m = p.matcher(s); - // Process the find information as you - // perform the replacements: - while(m.find()) - m.appendReplacement( - sbuf, m.group().toUpperCase()); - // Put in the remainder of the text: - m.appendTail(sbuf); - System.out.println(sbuf); - } + public static void main(String[] args) throws Exception { + String s = Files.lines( + Paths.get("TheReplacements.java")) + .collect(Collectors.joining("\n")); + // Match specially commented block of text above: + Matcher mInput = Pattern.compile( + "/\\*!(.*)!\\*/", Pattern.DOTALL).matcher(s); + if(mInput.find()) + s = mInput.group(1); // Captured by parentheses + // Replace two or more spaces with a single space: + s = s.replaceAll(" {2,}", " "); + // Replace 1+ spaces at the beginning of each + // line with no spaces. Must enable MULTILINE mode: + s = s.replaceAll("(?m)^ +", ""); + System.out.println(s); + s = s.replaceFirst("[aeiou]", "(VOWEL1)"); + StringBuffer sbuf = new StringBuffer(); + Pattern p = Pattern.compile("[aeiou]"); + Matcher m = p.matcher(s); + // Process the find information as you + // perform the replacements: + while(m.find()) + m.appendReplacement(sbuf, m.group().toUpperCase()); + // Put in the remainder of the text: + m.appendTail(sbuf); + System.out.println(sbuf); + } } /* Output: Here's a block of text to use as input to @@ -1257,39 +1265,39 @@ thE spEcIAl dElImItErs, thEn prOcEss thE ExtrActEd blOck. */ ``` -此处使用上一章介绍过的[`Files`](#)类打开并读入文件。`Files.lines()`返回一个`Stream`对象,包含读入的所有行,`Collectors.joining()`在每一行的结尾追加参数字符序列,最终拼接成一个`String`对象。 +此处使用上一章介绍过的 [`Files`](./17-Files.md) 类打开并读入文件。`Files.lines()` 返回一个 `Stream` 对象,包含读入的所有行,`Collectors.joining()` 在每一行的结尾追加参数字符序列,最终拼接成一个 `String` 对象。 -`mInput`匹配`/*!`和`!*/`之间的所有文字(注意分组的括号)。接下来,将存在两个或两个以上空格的地方,缩减为一个空格,并且删除每行开头部分的所有空格(为了使每一行都达到这个效果,而不仅仅是删除文本开头部分的空格,这里特意开启了多行模式)。这两个替换操作所使用的的`replaceAll()`是`String`对象自带的方法,在这里,使用此方法更方便。注意,因为这两个替换操作都只使用了一次`replaceAll()`,所以,与其编译为`Pattern`,不如直接使用`String`的`replaceAll()`方法,而且开销也更小些。 +`mInput` 匹配 `/*!` 和 `!*/` 之间的所有文字(注意分组的括号)。接下来,将存在两个或两个以上空格的地方,缩减为一个空格,并且删除每行开头部分的所有空格(为了使每一行都达到这个效果,而不仅仅是删除文本开头部分的空格,这里特意开启了多行模式)。这两个替换操作所使用的的 `replaceAll()` 是 `String` 对象自带的方法,在这里,使用此方法更方便。注意,因为这两个替换操作都只使用了一次 `replaceAll()`,所以,与其编译为 `Pattern`,不如直接使用 `String` 的 `replaceAll()` 方法,而且开销也更小些。 -`replaceFirst()`只对找到的第一个匹配进行替换。此外,`replaceFirst()`和`replaceAll()`方法用来替换的只是普通字符串,所以,如果想对这些替换字符串进行某些特殊处理,这两个方法时无法胜任的。如果你想要那么做,就应该使用`appendReplacement()`方法。该方法允许你在执行替换的过程中,操作用来替换的字符串。在这个例子中,先构造了`sbuf`用来保存最终结果,然后用`group()`选择一个组,并对其进行处理,将正则表达式找到的元音字母替换成大些字母。一般情况下,你应该遍历执行所有的替换操作,然后再调用`appendTail()`方法,但是,如果你想模拟`replaceFirst()`(或替换n次)的行为,那就只需要执行一次替换,然后调用`appendTail()`方法,将剩余未处理的部分存入`sbuf`即可。 +`replaceFirst()` 只对找到的第一个匹配进行替换。此外,`replaceFirst()` 和 `replaceAll()` 方法用来替换的只是普通字符串,所以,如果想对这些替换字符串进行某些特殊处理,这两个方法时无法胜任的。如果你想要那么做,就应该使用 `appendReplacement()` 方法。该方法允许你在执行替换的过程中,操作用来替换的字符串。在这个例子中,先构造了 `sbuf` 用来保存最终结果,然后用 `group()` 选择一个组,并对其进行处理,将正则表达式找到的元音字母替换成大些字母。一般情况下,你应该遍历执行所有的替换操作,然后再调用 `appendTail()` 方法,但是,如果你想模拟 `replaceFirst()`(或替换n次)的行为,那就只需要执行一次替换,然后调用 `appendTail()` 方法,将剩余未处理的部分存入 `sbuf` 即可。 -同时,`appendReplacement()`方法还允许你通过`\$g`直接找到匹配的某个组,这里的`g`就是组号。然而,它只能应付一些简单的处理,无法实现类似前面这个例子中的功能。 +同时,`appendReplacement()` 方法还允许你通过 `\$g` 直接找到匹配的某个组,这里的 `g` 就是组号。然而,它只能应付一些简单的处理,无法实现类似前面这个例子中的功能。 ### `reset()` -通过`reset()`方法,可以将现有的`Matcher`对象应用于一个新的字符序列: +通过 `reset()` 方法,可以将现有的 `Matcher` 对象应用于一个新的字符序列: ```java // strings/Resetting.java import java.util.regex.*; public class Resetting { - public static void main(String[] args) throws Exception { - Matcher m = Pattern.compile("[frb][aiu][gx]") - .matcher("fix the rug with bags"); - while(m.find()) - System.out.print(m.group() + " "); - System.out.println(); - m.reset("fix the rig with rags"); - while(m.find()) - System.out.print(m.group() + " "); - } + public static void main(String[] args) throws Exception { + Matcher m = Pattern.compile("[frb][aiu][gx]") + .matcher("fix the rug with bags"); + while(m.find()) + System.out.print(m.group() + " "); + System.out.println(); + m.reset("fix the rig with rags"); + while(m.find()) + System.out.print(m.group() + " "); + } } /* Output: fix rug bag fix rig rag */ ``` -使用不带参数的`reset()`方法,可以将`Matcher`对象重新设置到当前字符序列的起始位置。 -### 正则表达式与Java I/O -到目前为止,我们看到的例子都是将正则表达式用于静态的字符串。下面的例子将向你演示,如何应用正则表达式在一个文件中进行搜索匹配操作。`JGrep.java`的灵感源自于Unix上的*grep*。它有两个参数:文件名以及要匹配的正则表达式。输出的是每行有匹配的部分以及匹配部分在行中的位置。 +使用不带参数的 `reset()` 方法,可以将 `Matcher` 对象重新设置到当前字符序列的起始位置。 +### 正则表达式与 Java I/O +到目前为止,我们看到的例子都是将正则表达式用于静态的字符串。下面的例子将向你演示,如何应用正则表达式在一个文件中进行搜索匹配操作。`JGrep.java` 的灵感源自于 Unix 上的 *grep*。它有两个参数:文件名以及要匹配的正则表达式。输出的是每行有匹配的部分以及匹配部分在行中的位置。 ```java // strings/JGrep.java // A very simple version of the "grep" program @@ -1300,70 +1308,67 @@ import java.nio.file.*; import java.util.stream.*; public class JGrep {   - public static void main(String[] args) throws Exception {     - if(args.length < 2) {       - System.out.println(         - "Usage: java JGrep file regex");       - System.exit(0);   - }     - Pattern p = Pattern.compile(args[1]);     - // Iterate through the lines of the input file:     - int index = 0;     - Matcher m = p.matcher("");     - for(String line :         - Files.readAllLines(Paths.get(args[0]))) {       - m.reset(line);       - while(m.find())         - System.out.println(index++ + ": " +           - m.group() + ": " + m.start());   - } - } + public static void main(String[] args) throws Exception {     + if(args.length < 2) {       + System.out.println(         + "Usage: java JGrep file regex");       + System.exit(0);   + }     + Pattern p = Pattern.compile(args[1]);     + // Iterate through the lines of the input file:     + int index = 0;     + Matcher m = p.matcher("");     + for(String line: Files.readAllLines(Paths.get(args[0]))) {       + m.reset(line);       + while(m.find())         + System.out.println(index++ + ": " +           + m.group() + ": " + m.start());   + } + } } /* Output: 0: for: 4 1: for: 4 */ ``` -`Files.readAllLines()`返回一个`List`对象,这意味着可以用*for-in*进行遍历。虽然可以在`for`循环内部创建一个新的`Matcher`对象,但是,在循环体外创建一个空的`Matcher`对象,然后用`reset()`方法每次为`Matcher`加载一行输入,这种处理会有一定的性能优化。最后用`find()`搜索结果。 +`Files.readAllLines()` 返回一个 `List` 对象,这意味着可以用 *for-in* 进行遍历。虽然可以在 `for` 循环内部创建一个新的 `Matcher` 对象,但是,在循环体外创建一个空的 `Matcher` 对象,然后用 `reset()` 方法每次为 `Matcher` 加载一行输入,这种处理会有一定的性能优化。最后用 `find()` 搜索结果。 -这里读入的测试参数是`JGrep.java`文件,然后搜索一`[Ssct]`开头的单词。 +这里读入的测试参数是 `JGrep.java` 文件,然后搜索以 `[Ssct]` 开头的单词。 -如果想要更深入地学习正则表达式,你可以阅读Jeffrey E. F. Friedl的《精通正则表达式(第2版)》。网络上也有很多正则表达式的介绍,你还可以从Perl和Python等其他语言的文档中找到有用的信息。 +如果想要更深入地学习正则表达式,你可以阅读 Jeffrey E. F. Friedl 的《精通正则表达式(第2版)》。网络上也有很多正则表达式的介绍,你还可以从 Perl 和 Python 等其他语言的文档中找到有用的信息。 ## 扫描输入 -到目前为止,从文件或标准输入读取数据还是一件相当痛苦的事情。一般的解决办法就是读入一行文本,对其进行分词,然后使用`Integer`、`Double`等类的各种解析方法来解析数据: +到目前为止,从文件或标准输入读取数据还是一件相当痛苦的事情。一般的解决办法就是读入一行文本,对其进行分词,然后使用 `Integer`、`Double` 等类的各种解析方法来解析数据: ```java // strings/SimpleRead.java import java.io.*; public class SimpleRead {   - public static BufferedReader input =     - new BufferedReader(new StringReader(     - "Sir Robin of Camelot\n22 1.61803"));   - public static void main(String[] args) {     - try {       - System.out.println("What is your name?");       - String name = input.readLine();       - System.out.println(name);       - System.out.println("How old are you? " +         - "What is your favorite double?");       - System.out.println("(input: )");       - String numbers = input.readLine();       - System.out.println(numbers);       - String[] numArray = numbers.split(" ");       - int age = Integer.parseInt(numArray[0]);       - double favorite = Double.parseDouble(numArray[1]);       - System.out.format("Hi %s.%n", name);       - System.out.format("In 5 years you will be %d.%n",         - age + 5);       - System.out.format("My favorite double is %f.",         - favorite / 2);   - } catch(IOException e) {       - System.err.println("I/O exception");   - } - } + public static BufferedReader input =     + new BufferedReader(new StringReader(     + "Sir Robin of Camelot\n22 1.61803"));   + public static void main(String[] args) {     + try {       + System.out.println("What is your name?");       + String name = input.readLine();       + System.out.println(name);       + System.out.println("How old are you? " +         + "What is your favorite double?");       + System.out.println("(input: )");       + String numbers = input.readLine();       + System.out.println(numbers);       + String[] numArray = numbers.split(" ");       + int age = Integer.parseInt(numArray[0]);       + double favorite = Double.parseDouble(numArray[1]);       + System.out.format("Hi %s.%n", name);       + System.out.format("In 5 years you will be %d.%n", age + 5);       + System.out.format("My favorite double is %f.", favorite / 2);   + } catch(IOException e) {       + System.err.println("I/O exception");   + } + } } /* Output: What is your name? @@ -1376,11 +1381,11 @@ In 5 years you will be 27. My favorite double is 0.809015. */ ``` -`input`字段使用的类来自`java.io`,[`附录:I/O流`](#)详细介绍了相关内容。`StringReader`将`String`转化为可读的流对象,然后用这个对象来构造`BufferedReader`对象,因为我们要使用`BufferedReader`的`readLine()`方法。最终,我们可以使用`input`对象一次读取一行文本,就像从控制台读入标准输入一样。 +`input` 字段使用的类来自 `java.io`,[附录:流式 I/O](./Appendix-IO-Streams.md) 详细介绍了相关内容。`StringReader` 将 `String` 转化为可读的流对象,然后用这个对象来构造 `BufferedReader` 对象,因为我们要使用 `BufferedReader` 的 `readLine()` 方法。最终,我们可以使用 `input` 对象一次读取一行文本,就像从控制台读入标准输入一样。 -`readLine()`方法将一行输入转为`String`对象。如果每一行数据正好对应一个输入值,那这个方法也还可行。但是,如果两个输入值在同一行中,事情就不好办了,我们必须分解这个行,才能分别解析所需的输入值。在这个例子中,分解的操作发生在创建`numArray`时。 +`readLine()` 方法将一行输入转为 `String` 对象。如果每一行数据正好对应一个输入值,那这个方法也还可行。但是,如果两个输入值在同一行中,事情就不好办了,我们必须分解这个行,才能分别解析所需的输入值。在这个例子中,分解的操作发生在创建 `numArray`时。 -终于,Java SE5新增了`Scanner`类,它可以大大减轻扫描输入的工作负担: +终于,Java SE5 新增了 `Scanner` 类,它可以大大减轻扫描输入的工作负担: ```java // strings/BetterRead.java import java.util.*; @@ -1417,24 +1422,24 @@ In 5 years you will be 27. My favorite double is 0.809015. */ ``` -`Scanner`的构造器可以接收任意类型的输入对象,包括`File`对象、`InputStream`、`String`或者像此例中的`Readable`实现类。`Readable`是Java SE5中新加入的一个接口,表示“具有`read()`方法的某种东西”。上一个例子中的`BufferedReader`也归于这一类。 +`Scanner` 的构造器可以接收任意类型的输入对象,包括 `File`、`InputStream`、`String` 或者像此例中的`Readable` 实现类。`Readable` 是 Java SE5 中新加入的一个接口,表示“具有 `read()` 方法的某种东西”。上一个例子中的 `BufferedReader` 也归于这一类。 -有了`Scanner`,所有的输入、分词、以及解析的操作都隐藏在不同类型的`next`方法中。普通的`next()`方法返回下一个`String`。所有的基本类型(除`char`之外)都有对应的`next`方法,包括`BigDecimal`和`BigInteger`。所有的next方法,只有在找到一个完整的分词之后才会返回。`Scanner`还有相应的`hasNext`方法,用以判断下一个输入分词是否是所需的类型,如果是则返回`true`。 +有了 `Scanner`,所有的输入、分词、以及解析的操作都隐藏在不同类型的 `next` 方法中。普通的 `next()` 方法返回下一个 `String`。所有的基本类型(除 `char` 之外)都有对应的 `next` 方法,包括 `BigDecimal` 和 `BigInteger`。所有的 next 方法,只有在找到一个完整的分词之后才会返回。`Scanner` 还有相应的 `hasNext` 方法,用以判断下一个输入分词是否是所需的类型,如果是则返回 `true`。 -在`BetterRead.java`中没有用`try`区块捕获`IOException`。因为,`Scanner`有一个设假设,在输入结束时会抛出`IOException`,所以`Scanner`会把`IOException`吞掉。不过,通过`ioException()`方法,你可以找到最近发生的异常,因此,你可以在必要时检查它。 -### `Scanner`分隔符 -默认情况下,`Scanner`根据空白字符对输入进行分词,但是你可以用正则表达式指定自己所需的分隔符: +在 `BetterRead.java` 中没有用 `try` 区块捕获`IOException`。因为,`Scanner` 有一个假设,在输入结束时会抛出 `IOException`,所以 `Scanner` 会把 `IOException` 吞掉。不过,通过 `ioException()` 方法,你可以找到最近发生的异常,因此,你可以在必要时检查它。 +### `Scanner` 分隔符 +默认情况下,`Scanner` 根据空白字符对输入进行分词,但是你可以用正则表达式指定自己所需的分隔符: ```java // strings/ScannerDelimiter.java import java.util.*; public class ScannerDelimiter {   - public static void main(String[] args) {     - Scanner scanner = new Scanner("12, 42, 78, 99, 42");     - scanner.useDelimiter("\\s*,\\s*");     - while(scanner.hasNextInt())     - System.out.println(scanner.nextInt()); - } -} + public static void main(String[] args) {     + Scanner scanner = new Scanner("12, 42, 78, 99, 42");     + scanner.useDelimiter("\\s*,\\s*");     + while(scanner.hasNextInt())     + System.out.println(scanner.nextInt()); + } +} /* Output: 12 42 @@ -1443,7 +1448,7 @@ public class ScannerDelimiter {   42 */ ``` -这个例子使用逗号(包括逗号前后任意的空白字符)作为分隔符,同样的技术也可以用来读取逗号分隔的文件。我们可以用`useDelimiter()`来设置分隔符,同时,还有一个`delimiter()`方法,用来返回当前正在作为分隔符使用的`Pattern`对象。 +这个例子使用逗号(包括逗号前后任意的空白字符)作为分隔符,同样的技术也可以用来读取逗号分隔的文件。我们可以用 `useDelimiter()` 来设置分隔符,同时,还有一个 `delimiter()` 方法,用来返回当前正在作为分隔符使用的 `Pattern` 对象。 ### 用正则表达式扫描 除了能够扫描基本类型之外,你还可以使用自定义的正则表达式进行扫描,这在扫描复杂数据时非常有用。下面的例子将扫描一个防火墙日志文件中的威胁数据: ```java @@ -1451,26 +1456,26 @@ public class ScannerDelimiter {   import java.util.regex.*; import java.util.*; public class ThreatAnalyzer {  - static String threatData =     - "58.27.82.161@08/10/2015\n" +    - "204.45.234.40@08/11/2015\n" +     - "58.27.82.161@08/11/2015\n" +     - "58.27.82.161@08/12/2015\n" +     - "58.27.82.161@08/12/2015\n" + -    "[Next log section with different data format]";   - public static void main(String[] args) {  - Scanner scanner = new Scanner(threatData);     - String pattern = "(\\d+[.]\\d+[.]\\d+[.]\\d+)@" +       - "(\\d{2}/\\d{2}/\\d{4})";     - while(scanner.hasNext(pattern)) {       - scanner.next(pattern);       - MatchResult match = scanner.match();       - String ip = match.group(1);       - String date = match.group(2);       - System.out.format(         - "Threat on %s from %s%n", date,ip);   - } - } + static String threatData =     + "58.27.82.161@08/10/2015\n" +    + "204.45.234.40@08/11/2015\n" +     + "58.27.82.161@08/11/2015\n" +     + "58.27.82.161@08/12/2015\n" +     + "58.27.82.161@08/12/2015\n" + +     "[Next log section with different data format]";   + public static void main(String[] args) {  + Scanner scanner = new Scanner(threatData);     + String pattern = "(\\d+[.]\\d+[.]\\d+[.]\\d+)@" +       + "(\\d{2}/\\d{2}/\\d{4})";     + while(scanner.hasNext(pattern)) {       + scanner.next(pattern);       + MatchResult match = scanner.match();       + String ip = match.group(1);       + String date = match.group(2);       + System.out.format(         + "Threat on %s from %s%n", date,ip);   + } + } } /* Output: Threat on 08/10/2015 from 58.27.82.161 @@ -1480,32 +1485,31 @@ Threat on 08/12/2015 from 58.27.82.161 Threat on 08/12/2015 from 58.27.82.161 */ ``` -当`next()`方法配合指定的正则表达式使用时,将找到下一个匹配该模式的输入部分,调用`match()`方法就可以获得匹配的结果。如上所示,它的工作方式与之前看到的正则表达式匹配相似。 +当 `next()` 方法配合指定的正则表达式使用时,将找到下一个匹配该模式的输入部分,调用 `match()` 方法就可以获得匹配的结果。如上所示,它的工作方式与之前看到的正则表达式匹配相似。 在配合正则表达式使用扫描时,有一点需要注意:它仅仅针对下一个输入分词进行匹配,如果你的正则表达式中含有分隔符,那永远不可能匹配成功。 - + ## StringTokenizer类 -在Java引入正则表达式(J2SE1.4)和`Scanner`类(Java SE5)之前,分割字符串的唯一方法是使用`StringTokenizer`来分词。不过,现在有了正则表达式和`Scanner`,我们可以使用更加简单、更加简洁的方式来完成同样的工作了。下面的例子中,我们将`StringTokenizer`与另外两种技术简单地做了一个比较: +在 Java 引入正则表达式(J2SE1.4)和 `Scanner` 类(Java SE5)之前,分割字符串的唯一方法是使用 `StringTokenizer` 来分词。不过,现在有了正则表达式和 `Scanner`,我们可以使用更加简单、更加简洁的方式来完成同样的工作了。下面的例子中,我们将 `StringTokenizer` 与另外两种技术简单地做了一个比较: ```java // strings/ReplacingStringTokenizer.java import java.util.*; public class ReplacingStringTokenizer { - public static void main(String[] args) { - String input = - "But I'm not dead yet! I feel happy!"; - StringTokenizer stoke = new StringTokenizer(input); - while(stoke.hasMoreElements()) - System.out.print(stoke.nextToken() + " "); - System.out.println(); - System.out.println( - Arrays.toString(input.split(" "))); - Scanner scanner = new Scanner(input); - while(scanner.hasNext()) - System.out.print(scanner.next() + " "); - } + public static void main(String[] args) { + String input = + "But I'm not dead yet! I feel happy!"; + StringTokenizer stoke = new StringTokenizer(input); + while(stoke.hasMoreElements()) + System.out.print(stoke.nextToken() + " "); + System.out.println(); + System.out.println(Arrays.toString(input.split(" "))); + Scanner scanner = new Scanner(input); + while(scanner.hasNext()) + System.out.print(scanner.next() + " "); + } } /* Output: But I'm not dead yet! I feel happy! @@ -1513,12 +1517,12 @@ But I'm not dead yet! I feel happy! But I'm not dead yet! I feel happy! */ ``` -使用正则表达式或`Scanner`对象,我们能够以更加复杂的模式来分割一个字符串,而这对于`StringTokenizer`来说就很困难了。基本上,我们可以放心地说,`StringTokenizer`已经可以废弃不用了。 +使用正则表达式或 `Scanner` 对象,我们能够以更加复杂的模式来分割一个字符串,而这对于 `StringTokenizer` 来说就很困难了。基本上,我们可以放心地说,`StringTokenizer` 已经可以废弃不用了。 ## 本章小结 -过去,Java对于字符串操作的技术相当不完善。不过随着近几个版本的升级,我们可以看到,Java已经从其他语言中吸取了许多成熟的经验。到目前为止,它对字符串操作的支持已经很完善了。不过,有时你还要在细节上注意效率问题,例如恰当地使用`StringBuilder`等。 +过去,Java 对于字符串操作的技术相当不完善。不过随着近几个版本的升级,我们可以看到,Java 已经从其他语言中吸取了许多成熟的经验。到目前为止,它对字符串操作的支持已经很完善了。不过,有时你还要在细节上注意效率问题,例如恰当地使用 `StringBuilder` 等。 [^1]: C++允许编程人员任意重载操作符。这通常是很复杂的过程(参见Prentice Hall于2000年编写的《Thinking in C++(第2版)》第10章),因此Java设计者认为这是很糟糕的功能,不应该纳入到Java中。起始重载操作符并没有糟糕到只能自己去重载的地步,但具有讽刺意味的是,与C++相比,在Java中使用操作符重载要容易得多。这一点可以在Python(参见[www.Python.org](http://www.python.org))和C#中看到,它们都有垃圾回收机制,操作符重载也简单易懂。 @@ -1535,7 +1539,6 @@ But I'm not dead yet! I feel happy! [^5]: 我不知道他们是如何想出这个方法名的,或者它到底指的什么。这只是代码审查很重要的原因之一。 -
From 4050274cf4436e7c6ab006a44ec99e50a6d6bd46 Mon Sep 17 00:00:00 2001 From: Joe <736777445@qq.com> Date: Mon, 11 Nov 2019 10:23:50 +0800 Subject: [PATCH 3/4] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8b99e57..a06018a 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ - [x] [第十六章 代码校验](docs/book/16-Validating-Your-Code.md) - [x] [第十七章 文件](docs/book/17-Files.md) - [x] [第十八章 字符串](docs/book/18-Strings.md) -- [ ] [第十九章 类型信息](docs/book/19-Type-Information.md) +- [x] [第十九章 类型信息](docs/book/19-Type-Information.md) - [ ] [第二十章 泛型](docs/book/20-Generics.md) - [x] [第二十一章 数组](docs/book/21-Arrays.md) - [x] [第二十二章 枚举](docs/book/22-Enumerations.md) From fa0dafbaacda92a521ac12594950a74287cb7e08 Mon Sep 17 00:00:00 2001 From: 1326670425 <1326670425@qq.com> Date: Mon, 11 Nov 2019 17:48:47 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E7=AC=AC=E5=8D=81?= =?UTF-8?q?=E4=BA=8C=E7=AB=A0=20=E9=9B=86=E5=90=88=E6=8F=92=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/images/collection.png | Bin 58326 -> 51285 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/images/collection.png b/docs/images/collection.png index ab24df4466e7b844ae90f45cfba61a346e564802..a34dd0617a488690fdfc9cee1265ab97585dc1be 100644 GIT binary patch literal 51285 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