diff --git a/ch07/00_Reflection.md b/ch07/00_Reflection.md index 6e7f3af1..4abbabbd 100644 --- a/ch07/00_Reflection.md +++ b/ch07/00_Reflection.md @@ -6,6 +6,7 @@ 反射是一组功能的术语,它允许程序检查自己的定义。 `Java` 中的反射在类浏览器,对象检查器,调试器,解释器,服务(如 `JavaBeansTM` 和对象序列化)以及任何创 建,检查或操作任意 `Java` 对象的工具中发挥作用。 + `Java` 自一开始就出现了反射,但泛型的出现改变了反射的两种重要方式,即为泛型的反射和反射引入了泛型。 通过泛型来进行反射,我们指的是用于反射的一些类型现在是泛型类型。特别是,类 `Class` 成为泛型类 `Class`。这看起来可能会让人感到困惑,但一旦明白它可以 @@ -15,7 +16,10 @@ 通过对泛型的反思,我们的意思是反射现在返回有关泛型的信息。有一些新的接口可以表示泛型类型,包括类型变量,参数化类型和通配符类型,还有一些新的方法可以获得 泛型类型的字段,构造函数和方法。 +我们依次解释每一个点。我们不承担任何以前的反思知识,但我们专注于与泛型相关的方面。 + + 我们依次解释每一个点。我们不承担任何以前的反思知识,但我们专注于与泛型相关的方面。 《《《 [下一节](01_Generics_for_Reflection.md)
-《《《 [返回首页](../README.md) +《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch07/01_Generics_for_Reflection.md b/ch07/01_Generics_for_Reflection.md index 0fee3136..5da2ce21 100644 --- a/ch07/01_Generics_for_Reflection.md +++ b/ch07/01_Generics_for_Reflection.md @@ -3,9 +3,7 @@ ## 反射的泛型 -`Java` 支持自 `1.0` 版以来的反射以及 `1.1` 版以后的类文字。 它们的核心是 `Class` 类,它表示运行时对象类型的信息。 您可以编写一个类型,后跟 -`.class` 作为文字,表示与该类型相对应的类标记,并且方法 `getClass`在每个对象上定义并返回一个类标记,该标记表示该对象在运行时携带的特定类型信息。 这 -里是一个例子: +`Java` 支持自 `1.0` 版以来的反射以及 `1.1` 版以后的类文字。 它们的核心是 `Class` 类,它表示运行时对象类型的信息。 您可以编写一个类型,后跟 `.class` 作为文字,表示与该类型相对应的类标记,并且方法 `getClass` 在每个对象上定义并返回一个类标记,该标记表示该对象在运行时携带的特定类型信息。这里是一个例子: ```java Class ki = Integer.class; @@ -14,8 +12,7 @@ assert ki == kn; ``` -对于给定的类加载器,相同的类型总是由相同的类标记表示。为了强调这一点,在这里我们使用标识符(`==` 运算符)比较类标记。但是,在大多数情况下,使用相等 -等于方法)。 +对于给定的类加载器,相同的类型总是由相同的类标记表示。为了强调这一点,在这里我们使用标识符(`==` 运算符)比较类标记。但是,在大多数情况下,使用相等 等于方法)。 `Java 5` 中的一个变化是 `Class` 类现在接受一个类型参数,所以 `Class ` 是类型 `T` 的类标记的类型。 前面的代码现在写成如下所示: @@ -63,10 +60,10 @@ Retention r = k.getAnnotation(Retention.class); ``` -这种通用类型具有两个优点。 首先,这意味着调用结果不需要强制转换,因为泛型类型系统可以精确地指定正确的类型。 其次,这意味着如果您不小心使用类标记调用 -不是 `Annotation` 子类的类的方法,那么会在编译时而不是在运行时检测到。 -类标记的另一种用法类似于注释类,它出现在 `java.awt` 包的 `Component` 类的 `getListeners`` 方法中: +这种通用类型具有两个优点。 首先,这意味着调用结果不需要强制转换,因为泛型类型系统可以精确地指定正确的类型。其次,这意味着如果您不小心使用类标记调用不是 `Annotation` 子类的类的方法,那么会在编译时而不是在运行时检测到。 + +类标记的另一种用法类似于注释类,它出现在 `java.awt` 包的 `Component` 类的 `getListeners` 方法中: ```java public T[] getListeners(Class listenerType); @@ -74,16 +71,13 @@ 同样,这意味着 `getListeners` 的代码不需要强制转换,这意味着编译器可以检查该方法是否使用适当类型的类标记调用。 -作为类标记的一个有趣用法的最后一个示例,便捷类 `Collections` 包含一个构建包装的方法,该包装检查添加到给定列表或从给定列表中提取的每个元素是否属于给 -定类。 (其他集合类也有类似的方法,例如集合和地图。)它具有以下签名: +作为类标记的一个有趣用法的最后一个示例,便捷类 `Collections` 包含一个构建包装的方法,该包装检查添加到给定列表或从给定列表中提取的每个元素是否属于给定类。(其他集合类也有类似的方法,例如集合和地图。)它具有以下签名: ```java public static List checkedList(List l, Class k) ``` -包装在编译时通过动态检查来补充静态检查,这对于提高安全性或与遗留代码的接口(见第 `8.1` 节)可能很有用。 该实现调用前面描述的类 `Class` 中的方法,其 -中接收方是传递到方法中的类标记,并且该转换将应用于使用 `get`,`set` 或 `add` 添加到列表中的任何元素,或者将其写入列表中。 然而,`Class` 的类型 -参数意味着 `checkedList` 的代码不需要额外的转换(除了调用类类中的 `cast` 方法外),并且编译器可以检查该方法是否使用类标记调用 一个合适的类型。 +包装在编译时通过动态检查来补充静态检查,这对于提高安全性或与遗留代码的接口(见第 `8.1` 节)可能很有用。该实现调用前面描述的类 `Class` 中的方法,其中接收方是传递到方法中的类标记,并且该转换将应用于使用 `get`,`set` 或 `add` 添加到列表中的任何元素,或者将其写入列表中。然而,`Class` 的类型参数意味着 `checkedList` 的代码不需要额外的转换(除了调用类类中的 `cast` 方法外),并且编译器可以检查该方法是否使用类标记调用 一个合适的类型。 《《《 [下一节](02_Reflected_Types_are_Reifiable_Types.md)
-《《《 [返回首页](../README.md) +《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch07/02_Reflected_Types_are_Reifiable_Types.md b/ch07/02_Reflected_Types_are_Reifiable_Types.md index 1170e7e0..a971c7e3 100644 --- a/ch07/02_Reflected_Types_are_Reifiable_Types.md +++ b/ch07/02_Reflected_Types_are_Reifiable_Types.md @@ -63,4 +63,4 @@ 对类别标记的限制导致一个有用的属性。 无论何处出现类型为 `Class` 的类型,类型 `T` 都应该是可重用的类型。 对于 `T[]` 形式的类型也是如此. 《《《 [下一节](03_Reflection_for_Primitive_Types.md)
-《《《 [返回首页](../README.md) +《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch07/03_Reflection_for_Primitive_Types.md b/ch07/03_Reflection_for_Primitive_Types.md index ca200a0d..3b6f3460 100644 --- a/ch07/03_Reflection_for_Primitive_Types.md +++ b/ch07/03_Reflection_for_Primitive_Types.md @@ -18,4 +18,5 @@ 另一方面,`int[].class` 表示具有基本类型 `integer` 的组件的数组的类标记,并且此类标记的类型为 `Class`,这是允许的,因为 `int[]` 是引用类型。 《《《 [下一节](04_A_Generic_Reflection_Library.md)
-《《《 [返回首页](../README.md) + +《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch07/04_A_Generic_Reflection_Library.md b/ch07/04_A_Generic_Reflection_Library.md index 052f14d1..5b08fb2c 100644 --- a/ch07/04_A_Generic_Reflection_Library.md +++ b/ch07/04_A_Generic_Reflection_Library.md @@ -3,9 +3,7 @@ ## 一个通用的反射库 -正如我们所看到的,粗心使用未经检查的演员阵容可能会导致问题,例如违反广告中的真相原则或不雅暴露原则(参见第 `6.5` 节和第 `6.6` 节)。 最小化使用未经 -检查的强制转换的一种技术是将它们封装在库中。 该库可以仔细检查以确保其使用未经检查的强制转换是安全的,而调用该库的代码可以没有未经检查的强制转换。 -`Sun` 正在考虑添加类似于这里描述的库方法。 +正如我们所看到的,粗心使用未经检查的演员阵容可能会导致问题,例如违反广告中的真相原则或不雅暴露原则(参见第 `6.5` 节和第 `6.6` 节)。 最小化使用未经检查的强制转换的一种技术是将它们封装在库中。 该库可以仔细检查以确保其使用未经检查的强制转换是安全的,而调用该库的代码可以没有未经检查的强制转换。 `Sun` 正在考虑添加类似于这里描述的库方法。 例 `7-1` 提供了一个以类型安全的方式使用反射的通用函数库。 它定义了一个包含以下方法的便捷类 `GenericReflection`: @@ -16,23 +14,15 @@ public static T[] newArray(T[] a, int size) ``` -第一个接受一个对象,找到该对象的类,并返回该类的新实例;这必须与原始对象具有相同的类型。第二个接收数组并返回一个类标记作为其组件类型,如其运行时类型信 -息所携带的。相反,第三个分配一个新的数组,其组件类型由给定的类标记和指定的大小指定。第四个接受一个数组和一个大小,并且分配一个与给定数组和给定大小具 -有相同组件类型的新数组;它只是构成对前两种方法的调用。前三种方法中的每一种的代码都包含对 `Java` 反射库中一个或两个相应方法的调用,以及对相应返回类型的 -未检查转换。 +第一个接受一个对象,找到该对象的类,并返回该类的新实例;这必须与原始对象具有相同的类型。第二个接收数组并返回一个类标记作为其组件类型,如其运行时类型信息所携带的。相反,第三个分配一个新的数组,其组件类型由给定的类标记和指定的大小指定。第四个接受一个数组和一个大小,并且分配一个与给定数组和给定大小具有相同组件类型的新数组;它只是构成对前两种方法的调用。前三种方法中的每一种的代码都包含对 `Java` 反射库中一个或两个相应方法的调用,以及对相应返回类型的未检查转换。 -由于各种原因,`Java` 反射库中的方法无法返回足够精确的类型,因此需要未经检查的强制转换。方法 `getComponentType` 位于 `Class` 类中,并且 `Java` -无法将方法的签名中的接收方类型限制为 `Class `(尽管如果接收方不是类,该调用会引发异常令牌为数组类型)。 `java.lang.reflect.Array` 中的 -`newInstance` 方法必须具有返回类型 `Object` 而不是返回类型 `T[]`,因为它可能会返回基本类型的数组。方法 `getClass` 在类型 `T` 的接收器上调用时返回 -不是类型为 `Class ` 但类型 `Class `,因为需要擦除以确保类令牌始终具有可调整类型。但是,在每种情况下,未经检查的转换都是安全的,用 -户可以调用这里定义的四个库例程而不违反铸铁保证。 +由于各种原因,`Java` 反射库中的方法无法返回足够精确的类型,因此需要未经检查的强制转换。方法 `getComponentType` 位于 `Class` 类中,并且 `Java` 无法将方法的签名中的接收方类型限制为 `Class `(尽管如果接收方不是类,该调用会引发异常令牌为数组类型)。 `java.lang.reflect.Array` 中的 `newInstance` 方法必须具有返回类型 `Object` 而不是返回类型 `T[]`,因为它可能会返回基本类型的数组。方法 `getClass` 在类型 `T` 的接收器上调用时返回不是类型为 `Class ` 但类型 `Class `,因为需要擦除以确保类令牌始终具有可调整类型。但是,在每种情况下,未经检查的转换都是安全的,用户可以调用这里定义的四个库例程而不违反铸铁保证。 -例 `7-1`。 用于泛型反射的类型安全库 +例7-1。 用于泛型反射的类型安全库 ```java class GenericReflection { - public static T newInstance(T obj) throws InstantiationException, IllegalAccessException, - InvocationTargetException, NoSuchMethodException { + public static T newInstance(T obj) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { Object newobj = obj.getClass().getConstructor().newInstance(); return (T)newobj; // unchecked cast } @@ -52,16 +42,11 @@ } ``` -第一种方法优先于 `Class.newInstance` 使用 `Constructor.newInstance`(在 `java.lang.reflect` 中),以避免后者出现已知问题。引用 `Sun` 的 -`Class.newInstance` 文档:"请注意,此方法传播由 `nullary` 构造函数抛出的任何异常,包括检查的异常。使用此方法可以有效绕过编译时异常检查,否则编译器 -会执行该异常。 `Constructor.newInstance` 方法通过将构造函数抛出的任何异常包装在(`checked`)`InvocationTargetException` 中来避免此问题。" +第一种方法优先于 `Class.newInstance` 使用 `Constructor.newInstance`(在 `java.lang.reflect` 中),以避免后者出现已知问题。引用 `Sun` 的 `Class.newInstance` 文档:"请注意,此方法传播由 `nullary` 构造函数抛出的任何异常,包括检查的异常。使用此方法可以有效绕过编译时异常检查,否则编译器会执行该异常。 `Constructor.newInstance` 方法通过将构造函数抛出的任何异常包装在(`checked`)`InvocationTargetException` 中来避免此问题。" -第二种方法保证在任何遵循不雅曝光原则和广告真理原则的节目中都能很好地输入。第一个原则保证编译时的组件类型将是可重用的类型,然后第二个原则保证在运行时 -返回的通用组件类型必须是在编译时声明的可重用组件类型的子类型。 +第二种方法保证在任何遵循不雅曝光原则和广告真理原则的节目中都能很好地输入。第一个原则保证编译时的组件类型将是可重用的类型,然后第二个原则保证在运行时返回的通用组件类型必须是在编译时声明的可重用组件类型的子类型。 -如果第三种方法的类参数是基本类型,则会引发非法参数异常。这会捕获以下棘手的情况:如果第一个参数是 `int.class`,那么它的类型是 `Class`,但新 -数组的类型为 `int[]`,它不是 `Integer[]` 的子类型。如果 `int.class` 具有 `Class` 类型而不是 `Class` 类型,则不会出现此问题,如前一 -节所述。 +如果第三种方法的类参数是基本类型,则会引发非法参数异常。这会捕获以下棘手的情况:如果第一个参数是 `int.class`,那么它的类型是 `Class`,但新数组的类型为 `int[]`,它不是 `Integer[]` 的子类型。如果 `int.class` 具有 `Class` 类型而不是 `Class` 类型,则不会出现此问题,如前一节所述。 作为使用第一种方法的一个例子,下面是一个方法,它将一个集合复制到一个相同类型的新集合中,从而保留参数的类型: @@ -86,8 +71,7 @@ } ``` -一般来说,我们建议如果您需要使用未经检查的强制转换,那么您应该将它们封装到少数库方法中,就像我们在这里所做的那样。 不要让未经检查的代码在您的程序中激 -增! +一般来说,我们建议如果您需要使用未经检查的强制转换,那么您应该将它们封装到少数库方法中,就像我们在这里所做的那样。 不要让未经检查的代码在您的程序中激增! 《《《 [下一节](05_Reflection_for_Generics.md)
-《《《 [返回首页](../README.md) +《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch07/05_Reflection_for_Generics.md b/ch07/05_Reflection_for_Generics.md index 9e53fed1..1e88e123 100644 --- a/ch07/05_Reflection_for_Generics.md +++ b/ch07/05_Reflection_for_Generics.md @@ -85,4 +85,4 @@ 部分解释如何访问它。 《《《 [下一节](06_Reflecting_Generic_Types.md)
-《《《 [返回首页](../README.md) +《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch07/06_Reflecting_Generic_Types.md b/ch07/06_Reflecting_Generic_Types.md index 661047f2..027657a3 100644 --- a/ch07/06_Reflecting_Generic_Types.md +++ b/ch07/06_Reflecting_Generic_Types.md @@ -19,9 +19,7 @@ 方法可用于将类的超类和超接口作为类型返回,并访问字段的泛型类型,构造函数的参数类型以及方法的参数和结果类型。 -您还可以提取代表类或接口声明或泛型方法或构造函数的形式参数的类型变量。类型变量的类型需要一个参数,并写入 `TypeVariable`,其中 `D` 表示声明类型变 -量的对象的类型。因此,类的类型变量具有类型 `TypeVariable>`,而泛型方法的类型变量具有类型 `TypeVariable`。可以说,类型参数是令人 -困惑的,并不是非常有用。由于它对 `6.6` 节中描述的问题负责,因此 `Sun` 可能会在将来删除它。 +您还可以提取代表类或接口声明或泛型方法或构造函数的形式参数的类型变量。类型变量的类型需要一个参数,并写入 `TypeVariable`,其中 `D` 表示声明类型变量的对象的类型。因此,类的类型变量具有类型 `TypeVariable>`,而泛型方法的类型变量具有类型 `TypeVariable`。可以说,类型参数是令人困惑的,并不是非常有用。由于它对 `6.6` 节中描述的问题负责,因此 `Sun` 可能会在将来删除它。 例 `7-5` 使用这些方法打印出与类关联的所有标题信息。这里有两个使用例子: diff --git a/ch08/00_Effective_Generics.md b/ch08/00_Effective_Generics.md index 27b5c15b..3d53e5d3 100644 --- a/ch08/00_Effective_Generics.md +++ b/ch08/00_Effective_Generics.md @@ -1,3 +1,9 @@ +《《《 [返回首页](../README.md)
+《《《 [上一节](../ch07/06_Reflecting_Generic_Types.md) + ## 有效的泛型 -本章包含如何在实际编码中有效使用泛型的建议。 我们考虑检查集合,安全问题,专用类和二进制兼容性。 本节的标题是对 `Joshua Bloch` 的着作 `Effective Java(Addison-Wesley)`的致敬。 \ No newline at end of file +本章包含如何在实际编码中有效使用泛型的建议。 我们考虑检查集合,安全问题,专用类和二进制兼容性。 本节的标题是对 `Joshua Bloch` 的着作 `Effective Java(Addison-Wesley)` 的致敬。 + +《《《 [下一节](01_Take_Care_when_Callin_Legacy_Code.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch08/01_Take_Care_when_Callin_Legacy_Code.md b/ch08/01_Take_Care_when_Callin_Legacy_Code.md index 7e1b71dc..7adbbcef 100644 --- a/ch08/01_Take_Care_when_Callin_Legacy_Code.md +++ b/ch08/01_Take_Care_when_Callin_Legacy_Code.md @@ -1,3 +1,6 @@ +《《《 [返回首页](../README.md)
+《《《 [上一节](00_Effective_Generics.md) + ## 调用遗留代码时要小心 正如我们所看到的,泛型类型在编译时被检查,而不是运行时。 通常,这正是我们想要的,因为在编译时检查会更早地报告错误,并且不会导致运行时开销。 但是,有时这可能不合适,因为我们无法确定编译时检查是否足够(比如说,因为我们将参数化类型的实例传递给旧客户端或我们不信任的客户端 ),还是因为我们在运行时需要关于类型的信息(比如说,因为我们需要一个可重用类型作为数组组件)。 一个托收集合通常会诀窍,如果不行,我们可以创建一个专门的类。 我们考虑本节中的已检查集合,下一节中的安全问题以及之后的部分中的专门类。 @@ -59,7 +62,8 @@ 仅当列表元素具有可确定类型时,检查列表才提供有用的保证。 如果你想在列表不是可确定类型时应用这些技术,你可能需要考虑应用 `8.3` 节的专门化技术。 - +《《《 [下一节](02_Use_Checked_Collections_to_Enforce_Security.md)
+《《《 [返回首页](../README.md) diff --git a/ch08/02_Use_Checked_Collections_to_Enforce_Security.md b/ch08/02_Use_Checked_Collections_to_Enforce_Security.md index 98440115..81475903 100644 --- a/ch08/02_Use_Checked_Collections_to_Enforce_Security.md +++ b/ch08/02_Use_Checked_Collections_to_Enforce_Security.md @@ -1,3 +1,6 @@ +《《《 [返回首页](../README.md)
+《《《 [上一节](01_Take_Care_when_Callin_Legacy_Code.md) + ## 使用选中的集合来强化安全性 请注意,通用类型提供的保证仅适用于没有未经检查的警告的情况。 这意味着泛型类型对于确保其他人编写的代码的安全性没有用处,因为您无法知道该代码是否在编译时引发未经检查的警告。 @@ -65,7 +68,8 @@ 选中的集合不是实施安全性的唯一技术。 如果提供订单的接口返回一个列表而不是接受一个列表,那么代理可以使用前一节中的空循环技术来确保列表只包含经过授权的订单,然后才能通过它们。 也可以使用专业化,如下一节所述,创建一个特殊类型的列表,只能包含授权订单。 - +《《《 [下一节](03_Specialize_to_Create_Reifiable_Types.md)
+《《《 [返回首页](../README.md) diff --git a/ch08/03_Specialize_to_Create_Reifiable_Types.md b/ch08/03_Specialize_to_Create_Reifiable_Types.md index 91d3b728..c4bcb228 100644 --- a/ch08/03_Specialize_to_Create_Reifiable_Types.md +++ b/ch08/03_Specialize_to_Create_Reifiable_Types.md @@ -1,3 +1,6 @@ +《《《 [返回首页](../README.md)
+《《《 [上一节](02_Use_Checked_Collections_to_Enforce_Security.md) + ## 专注于创建可维持类型 参数化类型不可确定,但某些操作(如实例测试,转换和数组创建仅适用于可重用类型)。 在这种情况下,一种解决方法是创建参数化类型的专用版本。 专业版本可以通过委托(即包装)或继承(即子类化)来创建,我们依次讨论每个版本。 @@ -164,7 +167,8 @@ 这有两个问题:第一个接口使用相同的擦除扩展了两个不同的接口,这是不允许的(见 `4.4` 节),而第二个接口的顶级使用通配符的超类型,这也是不允许的 见 `2.8` 节)。 唯一的解决方法是避免包含通配符的类型的专业化; 幸运的是,这应该很少成为问题。 - +《《《 [下一节](04_Maintain_Binary_Compatibility.md)
+《《《 [返回首页](../README.md) diff --git a/ch08/04_Maintain_Binary_Compatibility.md b/ch08/04_Maintain_Binary_Compatibility.md index e043f769..e77e62fa 100644 --- a/ch08/04_Maintain_Binary_Compatibility.md +++ b/ch08/04_Maintain_Binary_Compatibility.md @@ -1,3 +1,6 @@ +《《《 [返回首页](../README.md)
+《《《 [上一节](03_Specialize_to_Create_Reifiable_Types.md) + ## 保持二进制兼容性 正如我们强调的那样,泛型是通过擦除来实现的,以缓解进化。当将遗留代码转化为泛型代码时,我们希望确保新生代码能够与任何现有代码一起工作,包括我们没有源代码的类文件。当这种情况发生时,我们说传统和通用版本是二进制兼容的。 @@ -204,7 +207,8 @@ 这保证与用户可能定义的任何子类兼容。 同样,如果你还可以生成任何子类,或者如果这个类是最终的,那么你有更多的自由。 - +《《《 [下一节](../ch09/00_Design_Patterns.md)
+《《《 [返回首页](../README.md) diff --git a/ch09/00_Design_Patterns.md b/ch09/00_Design_Patterns.md index 67897e5f..93d575df 100644 --- a/ch09/00_Design_Patterns.md +++ b/ch09/00_Design_Patterns.md @@ -1,3 +1,9 @@ +《《《 [返回首页](../README.md)
+《《《 [上一节](../ch08/04_Maintain_Binary_Compatibility.md) + ## 设计模式 -本章回顾了五种着名的设计模式 - 访问者,解释器,函数,策略和主题观察者,并展示了他们如何利用泛型。函数模式概括了比较器接口的思想。 其他四种模式在 `Gamma`,`Helm`,`Johnson` 和 `Vlissides`(`Addison-Wesley`)的开创性设计模式中描述。 \ No newline at end of file +本章回顾了五种着名的设计模式 - 访问者,解释器,函数,策略和主题观察者,并展示了他们如何利用泛型。函数模式概括了比较器接口的思想。 其他四种模式在 `Gamma`,`Helm`,`Johnson` 和 `Vlissides`(`Addison-Wesley`)的开创性设计模式中描述。 + +《《《 [下一节](01_Visitor.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch09/01_Visitor.md b/ch09/01_Visitor.md index b192210d..7a6adbf9 100644 --- a/ch09/01_Visitor.md +++ b/ch09/01_Visitor.md @@ -1,3 +1,6 @@ +《《《 [返回首页](../README.md)
+《《《 [上一节](00_Design_Patterns.md) + ## 游客 通常情况下,数据结构由案例分析和递归定义。例如,`Tree` 类型的二叉树是以下之一: @@ -172,7 +175,5 @@ } } ``` - - - - +《《《 [下一节](02_Interpreter.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch09/02_Interpreter.md b/ch09/02_Interpreter.md index 88bedd24..8c916ba7 100644 --- a/ch09/02_Interpreter.md +++ b/ch09/02_Interpreter.md @@ -1,3 +1,6 @@ +《《《 [返回首页](../README.md)
+《《《 [上一节](01_Visitor.md) + ## 翻译员 树的一种用法是用编程语言表示表达式。如前一节所述,表达式类型由一个抽象类表示,每种表达式都由一个子类表示。有一种抽象方法来评估一个表达式,并且每个子类都根据相应的表达式实现该方法。 @@ -16,5 +19,5 @@ `Java` 中的泛型受到功能语言(如 `ML` 和 `Haskell` )中类似功能的启发。通用的解释器模式很有趣,因为它展示了一种Java中的泛型比其他语言中的泛型更强大的方式。虽然最近的 `Haskell` 版本包含了一个实验性特征,即通用抽象数据类型,它专门为支持这种模式而设计,但在 `ML` 和 `Haskell` 的标准版本中实现这种模式是不可能的。 - - +《《《 [下一节](03_Function.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch09/03_Function.md b/ch09/03_Function.md index 5b114107..ba2f3b92 100644 --- a/ch09/03_Function.md +++ b/ch09/03_Function.md @@ -1,3 +1,6 @@ +《《《 [返回首页](../README.md)
+《《《 [上一节](02_Interpreter.md) + ## 功能 函数模式将任意方法转换为对象。函数和相应方法之间的关系类似于 `Comparator` 和 `compareTo` 方法之间的关系。 @@ -103,33 +106,5 @@ 该异常会引发两次,一次是在应用 `forName` 时,一次是在应用 `getRunMethod` 时引发的。 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +《《《 [下一节](04_Strategy.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch09/04_Strategy.md b/ch09/04_Strategy.md index 78e86511..eef4d601 100644 --- a/ch09/04_Strategy.md +++ b/ch09/04_Strategy.md @@ -1,3 +1,6 @@ +《《《 [返回首页](../README.md)
+《《《 [上一节](03_Function.md) + ## 策略 策略模式用于将方法与对象分离,使您可以提供许多可能的方法实例。我们对战略模式的讨论说明了许多面向对象程序中的结构化技术,即并行类层次结构。我们将通过考虑纳税人如何应用不同的税收策略来说明战略模式。纳税人将会有一个等级制度,并且有一个相关的税收策略等级制度。例如,有一个适用于任何纳税人的默认策略。纳税人的一个子类是信任,而默认策略的一个子类只适用于信任。 @@ -226,9 +229,5 @@ 我们将在下一节看到递归类型参数的另一个例子,它应用于两个相互递归的类。 不过,虽然 `getThis` 技巧通常很有用,但我们不会要求它。 - - - - - - +《《《 [下一节](05_Subject-Observer.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch09/05_Subject-Observer.md b/ch09/05_Subject-Observer.md index 2d97ef5c..e499bea8 100644 --- a/ch09/05_Subject-Observer.md +++ b/ch09/05_Subject-Observer.md @@ -1,3 +1,6 @@ +《《《 [返回首页](../README.md)
+《《《 [上一节](04_Strategy.md) + ## 主题观察者 我们用一个更加扩展的例子来完成,说明通用的 `Subject-Observer` 模式。与策略模式一样,`Subject-Observer` 模式使用并行类层次结构,但这次我们需要两个具有相互递归边界的类型变量,一个代表特定类型的主体,一个代表特定类型的观察者。这是我们的第一个带有相互递归边界的类型变量的例子。 @@ -220,19 +223,5 @@ CModel类有一个方法来设置和获取给定货币的汇率和价值。汇 泛型最重要的用途之一是集合框架,在本书的下一部分,我们将向您展示如何有效地使用此框架并提高您作为 `Java` 程序员的工作效率。 - - - - - - - - - - - - - - - - +《《《 [下一节](../ch10/00_Collections.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch10/00_Collections.md b/ch10/00_Collections.md index cd3013f0..17bbf03f 100644 --- a/ch10/00_Collections.md +++ b/ch10/00_Collections.md @@ -1,50 +1,11 @@ +《《《 [返回首页](../README.md)
+《《《 [上一节](../ch09/05_Subject-Observer.md) + # 集合 `Java` 集合框架是 `java.util` 和 `java.util.concurrent` 包中的一组接口和类。他们为客户程序提供了如何组织其对象的各种模型以及每种模型的各种实现。这些模型有时被称为抽象数据类型,我们需要它们,因为不同的程序需要不同的方式来组织它们的对象。在一种情况下,您可能希望将程序的对象组织在顺序列表中,因为它们的排序很重要,并且有重复。另一种情况是,一个集合可能是正确的数据类型,因为现在的排序并不重要,你想放弃重复。这两种数据类型(以及其他)由集合框架中的不同接口表示,我们将在本章中查看它们的使用示例。但那不是全部;这些数据类型中没有一个具有单一的"最佳"实现 - 也就是说,对于所有操作,其中一个实现比所有其他实现更好。例如,链接列表可能比用于从中间插入和删除元素的列表的阵列实现更好,但是对于随机访问更糟糕。因此,为您的程序选择正确的实施方式涉及知道如何使用以及可用的方式。 本书的这一部分首先概述框架,然后详细介绍每个主界面及其标准实现。最后,我们将看看 `Collections` 类中提供的专用实现和通用算法。 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +《《《 [下一节](01_The_Main_Interfaces_of_the_Java.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch10/01_The_Main_Interfaces_of_the_Java.md b/ch10/01_The_Main_Interfaces_of_the_Java.md index d55093b1..e4280d7b 100644 --- a/ch10/01_The_Main_Interfaces_of_the_Java.md +++ b/ch10/01_The_Main_Interfaces_of_the_Java.md @@ -1,3 +1,6 @@ +《《《 [返回首页](../README.md)
+《《《 [上一节](00_Collections.md) + ## Java集合框架的主要接口 图 `10-1` 显示了 `Java` 集合框架的主要接口,以及另外一个 `Iterable`--它不在框架中,但是它是一个重要的附件。其目的如下: @@ -14,4 +17,7 @@ 图 `10-1`。 `Java`集合框架的主要接口 -第 `12` 章到第 `16` 章将依次关注每个集合框架接口。首先,虽然在第 `11` 章中,我们需要介绍贯穿整个框架设计的一些初步想法。 \ No newline at end of file +第 `12` 章到第 `16` 章将依次关注每个集合框架接口。首先,虽然在第 `11` 章中,我们需要介绍贯穿整个框架设计的一些初步想法。 + +《《《 [下一节](../ch11/00_Preliminaries.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch11/00_Preliminaries.md b/ch11/00_Preliminaries.md index 3157eb8c..c190ece5 100644 --- a/ch11/00_Preliminaries.md +++ b/ch11/00_Preliminaries.md @@ -1,3 +1,9 @@ +《《《 [返回首页](../README.md)
+《《《 [上一节](../ch10/01_The_Main_Interfaces_of_the_Java.md) + ## 初步措施 -在本章中,在深入讨论集合本身的细节之前,我们将花时间讨论框架的基本概念。 \ No newline at end of file +在本章中,在深入讨论集合本身的细节之前,我们将花时间讨论框架的基本概念。 + +《《《 [下一节](01_Iterable_and_Iterators.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch11/01_Iterable_and_Iterators.md b/ch11/01_Iterable_and_Iterators.md index 16fb0938..4a50ef20 100644 --- a/ch11/01_Iterable_and_Iterators.md +++ b/ch11/01_Iterable_and_Iterators.md @@ -1,3 +1,6 @@ +《《《 [返回首页](../README.md)
+《《《 [上一节](00_Preliminaries.md) + ## 可迭代和迭代器 迭代器是实现接口迭代器的对象 @@ -73,18 +76,5 @@ public Iterator { 并发集合有处理并发修改的其他策略,例如弱一致的迭代器。 我们在第 `11.5` 节更详细地讨论它们。 - - - - - - - - - - - - - - - +《《《 [下一节](02_Implementations.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch11/02_Implementations.md b/ch11/02_Implementations.md index 5a3747e8..d9c63b55 100644 --- a/ch11/02_Implementations.md +++ b/ch11/02_Implementations.md @@ -1,3 +1,6 @@ +《《《 [返回首页](../README.md)
+《《《 [上一节](01_Iterable_and_Iterators.md) + ## 实现 我们简要地看了一下集合框架的接口,这些接口定义了我们可以预期的每个集合的行为。但正如我们在本章的介绍中提到的,有几种方法可以实现每个接口。为什么框架不会为每个接口使用最佳实现?那肯定会让生活变得更简单 - 事实上,过于简单就像生活一样。如果实施对某些行动来说是灰狗,墨菲定律告诉我们这对其他人来说将是一只乌龟。由于没有任何接口的"最佳"实现,所以您必须进行权衡,判断应用程序中哪些操作最常使用,并选择优化这些操作的实现。 @@ -28,3 +31,5 @@ - 这些也按内容来组织它们的元素,但重要的区别是它们可以按排序顺序存储和检索它们。它们对于插入和删除元素,通过内容访问它们并迭代它们的操作相对较快。 树是 `TreeSet` 和 `TreeMap` 的支持结构。 在执行 `PriorityQueue` 和 `PriorityBlockingQueue` 时使用的优先堆是与树有关的结构。 +《《《 [下一节](03_Efficiency_and_the_O-Notation.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch11/03_Efficiency_and_the_O-Notation.md b/ch11/03_Efficiency_and_the_O-Notation.md index 24a5b539..2532eccd 100644 --- a/ch11/03_Efficiency_and_the_O-Notation.md +++ b/ch11/03_Efficiency_and_the_O-Notation.md @@ -1,3 +1,6 @@ +《《《 [返回首页](../README.md)
+《《《 [上一节](02_Implementations.md) + ## 效率与Ο符号 在最后一节中,我们讨论了不同的实现对于不同的操作是"好的"。一个好的算法在使用两种资源时很经济:时间和空间。集合的实现通常使用与集合大小成正比的空间,但是访问和更新所需的时间可能会有很大差异,所以这将是我们的主要关心。很难说一个程序执行的速度有多快,因为这取决于很多因素,包括程序员省外的一些因素,比如编译代码的质量和硬件的速度。即使我们忽略了这些并且仅仅考虑算法的执行时间如何依赖于它的数据,详细的分析可能是复杂的。在 `Donald Knuth` 的经典着作"排序和搜索"(`Addison-Wesley`)中提供了一个相对简单的例子, `Knuth` 的名义 `MIX` 机器上的多列表插入排序程序的最坏情况执行时间推导为 @@ -29,5 +32,5 @@ O(2^N)的算法来解决 - 对于这些,当N加倍时,运行时间是平 下,我们计算操作的摊销成本 - 即执行 `n` 次的总成本除以 `n`,当 `n` 变得任意大时,将其取为极限。在向 `ArrayList` 添加元素的情况下,`N` 个元素的总成 本为 `O(N)`,因此摊余成本为 `O(1)`。 - - +《《《 [下一节](04_contract.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch11/04_contract.md b/ch11/04_contract.md index dd223748..c2fcd1e4 100644 --- a/ch11/04_contract.md +++ b/ch11/04_contract.md @@ -1,3 +1,6 @@ +《《《 [返回首页](../README.md)
+《《《 [上一节](03_Efficiency_and_the_O-Notation.md) + ## 契约 在阅读软件设计时,你很可能会遇到合同一词,通常没有任何附带的解释。事实上,软件工程给这个术语的含义非常接近人们通常理解合同的含义。在日常使用中,合同定 @@ -29,8 +32,5 @@ 定; 虽然合约具有约束力,但使用它们的主要优点之一是它们允许实现在更好的算法被发现时改变,或者随着硬件改进改变它们的相对优点。 当然,如果你正在使用另一 个实现,比如 `GNU Classpath`,那么不受合同约束的算法细节可能完全不同。 - - - - - +《《《 [下一节](05_Collections_and_Thread_Safety.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch11/05_Collections_and_Thread_Safety.md b/ch11/05_Collections_and_Thread_Safety.md index 1f054cc2..0e8051d1 100644 --- a/ch11/05_Collections_and_Thread_Safety.md +++ b/ch11/05_Collections_and_Thread_Safety.md @@ -1,3 +1,6 @@ +《《《 [返回首页](../README.md)
+《《《 [上一节](04_contract.md) + ## 集合和线程安全 当一个 `Java` 程序正在运行时,它正在执行一个或多个执行流或线程。 线程就像一个轻量级进程,所以同时执行多个线程的程序可以被认为是同时运行多个程序的计算 @@ -140,5 +143,5 @@ 上述第三组也具有弱一致的迭代器。 在 `Java 6` 中,这包括 `DelayQueue` 和 `PriorityBlockingQueue`,它们在 `Java 5` 中具有快速迭代器。这意味着,除非这些队列是静态的,否则当不添加或插入元素时,您不能迭代这些队列的 `Java 5` 版本; 在其他时候,你必须使用 `toArray` 将它们的元素复制到一个数组中,然后遍历它。 - - +《《《 [下一节](../ch12/00_The_Collection_Interface.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch12/00_The_Collection_Interface.md b/ch12/00_The_Collection_Interface.md index dd538b54..203e9cef 100644 --- a/ch12/00_The_Collection_Interface.md +++ b/ch12/00_The_Collection_Interface.md @@ -1,3 +1,6 @@ +《《《 [返回首页](../README.md)
+《《《 [上一节](../ch11/05_Collections_and_Thread_Safety.md) + ### 集合接口 接口集合(参见图 `12-1`)定义了我们期望的除地图以外的任何集合的核心功能。 它提供了四组中的方法。 @@ -101,4 +104,7 @@ for (int i=0; i +《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch12/01_Using_the_Methods_of_Collection.md b/ch12/01_Using_the_Methods_of_Collection.md index e47088d3..bdeb46ba 100644 --- a/ch12/01_Using_the_Methods_of_Collection.md +++ b/ch12/01_Using_the_Methods_of_Collection.md @@ -1,3 +1,5 @@ +《《《 [返回首页](../README.md)
+《《《 [上一节](00_The_Collection_Interface.md) ### 使用集合方法 @@ -247,19 +249,5 @@ "[code db, code gui, code logic, phone Mike, phone Paul]"); ``` - - - - - - - - - - - - - - - - +《《《 [下一节](02_Implementing_Collection.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch12/02_Implementing_Collection.md b/ch12/02_Implementing_Collection.md index 063a1f1a..13900825 100644 --- a/ch12/02_Implementing_Collection.md +++ b/ch12/02_Implementing_Collection.md @@ -1,6 +1,9 @@ - +《《《 [返回首页](../README.md)
+《《《 [上一节](01_Using_the_Methods_of_Collection.md) ### 集合实现 `Collection` 没有具体的实现。 类 `AbstractCollection` 部分实现它,它是一系列骨架实现中的一个 - 包括 `AbstractSet`,`AbstractList`等 - 它们提供了每个接口的不同具体实现的通用功能。 这些框架实现可用于帮助框架接口的新实现的设计者。例如,`Collection` 可以作为包(无序列表)的接口,而实现包的程序员可以扩展 `AbstractCollection` 并查找大部分已经完成的实现工作。 +《《《 [下一节](03_Collection_Constructors.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch12/03_Collection_Constructors.md b/ch12/03_Collection_Constructors.md index 5e8c20cb..8c1ebcea 100644 --- a/ch12/03_Collection_Constructors.md +++ b/ch12/03_Collection_Constructors.md @@ -1,4 +1,5 @@ - +《《《 [返回首页](../README.md)
+《《《 [上一节](02_Implementing_Collection.md) ### 集合构造函数 @@ -13,7 +14,5 @@ 并非所有集合类都具有这两种形式的构造函数 - 例如,`ArrayBlockingQueue` 不能在未修复其容量的情况下创建,并且 `SynchronousQueue` 根本不能容纳任何元素,因此不需要第二种形式的构造函数。另外,许多集合类除了这两个以外还有其他构造函数,但是它们所拥有的不是它们所实现的接口,而是取决于底层实现;这些额外的构造函数用于配置实现。 - - - - +《《《 [下一节](../ch13/00_Sets.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch13/00_Sets.md b/ch13/00_Sets.md index 415009f5..4bf8f768 100644 --- a/ch13/00_Sets.md +++ b/ch13/00_Sets.md @@ -1,5 +1,5 @@ - - +《《《 [返回首页](../README.md)
+《《《 [上一节](../ch12/03_Collection_Constructors.md) ## Sets @@ -13,13 +13,5 @@ 这是因为处理重复元素的方式。 在星期一任务和电话任务中的任务麦克电话,只有一次出现在 `phoneAndMondayTasks 中 - 你绝对不希望两次完成所有这些任务! - - - - - - - - - - +《《《 [下一节](01_Implementing_Set.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch13/01_Implementing_Set.md b/ch13/01_Implementing_Set.md index afda761b..fd1f349e 100644 --- a/ch13/01_Implementing_Set.md +++ b/ch13/01_Implementing_Set.md @@ -1,5 +1,5 @@ - - +《《《 [返回首页](../README.md)
+《《《 [上一节](00_Sets.md) ## 实现Set @@ -138,29 +138,7 @@ 在使用中,`EnumSet` 服从 `Set` 的约定,并添加了它的迭代器将以自然顺序(声明 `enum` 常量的顺序)返回它们的元素的规范。 它不是线程安全的,但与不同步的通用集合不同,它的迭代器不是快速失败的。 它们可能是快照或弱一致的;保守,合约只能保证它们会弱一致(见第 `11.5` 节)。 ![](13_3.png) -图 `13-4`。`SortedSet` 的 - - - - - - - - - - - - - - - - - - - - - - - - +图 `13-4`。`SortedSet` 的 +《《《 [下一节](02_SortedSet_and_NavigableSet.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch13/02_SortedSet_and_NavigableSet.md b/ch13/02_SortedSet_and_NavigableSet.md index f01dae17..8dda4d89 100644 --- a/ch13/02_SortedSet_and_NavigableSet.md +++ b/ch13/02_SortedSet_and_NavigableSet.md @@ -1,5 +1,5 @@ - - +《《《 [返回首页](../README.md)
+《《《 [上一节](01_Implementing_Set.md) ## SortedSet和NavigableSet @@ -315,4 +315,5 @@ 在 `EnumSet` 实现中,对于多于 `64` 个值的枚举类型,下一个最坏情况下的复杂度为 `O(log m)`,其中 `m` 是枚举中元素的数量。 - +《《《 [下一节](../ch14/00_Queues.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch14/00_Queues.md b/ch14/00_Queues.md index d76b6427..b61f5af5 100644 --- a/ch14/00_Queues.md +++ b/ch14/00_Queues.md @@ -1,4 +1,5 @@ - +《《《 [返回首页](../README.md)
+《《《 [上一节](../ch13/02_SortedSet_and_NavigableSet.md) # Queues @@ -44,5 +45,5 @@ 由于这些方法返回 `null` 以表示队列为空,因此应避免将 `null` 用作队列元素。 通常,`Queue` 接口不鼓励使用 `null` 作为队列元素,并且允许它的唯一标准实现是传统实现 `LinkedList`。 - - +《《《 [下一节](01_Using_the_Methods_of_Queue.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch14/01_Using_the_Methods_of_Queue.md b/ch14/01_Using_the_Methods_of_Queue.md index 56fb1254..ef6c559b 100644 --- a/ch14/01_Using_the_Methods_of_Queue.md +++ b/ch14/01_Using_the_Methods_of_Queue.md @@ -1,5 +1,5 @@ - - +《《《 [返回首页](../README.md)
+《《《 [上一节](00_Queues.md) ## 使用队列方法 @@ -49,3 +49,5 @@ 在下一节中,我们将看看 `Queue` - `Priority Queue` 和 `ConcurrentLinkedList` 的直接实现 - 以及 `14.3` 章节中的 `BlockingQueue` 及其实现。这两节中的课程在行为上差异很大。他们大多数是线程安全的;大多数提供阻塞设施(即等待条件的操作适合他们执行);一些支持优先级排序;一个 `DelayQueue` - 保留元素,直到它们的延迟已经过期,另一个 - 同步队列 - 完全是一个同步工具。在队列实现之间进行选择时,这些功能差异会比他们的表现更受影响。 +《《《 [下一节](02_Implementing_Queue.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch14/02_Implementing_Queue.md b/ch14/02_Implementing_Queue.md index 3dc769b6..e1efca36 100644 --- a/ch14/02_Implementing_Queue.md +++ b/ch14/02_Implementing_Queue.md @@ -1,5 +1,5 @@ - - +《《《 [返回首页](../README.md)
+《《《 [上一节](01_Using_the_Methods_of_Queue.md) ## 队列的实现 @@ -64,3 +64,5 @@ `ConcurrentLinkedQueue` 有 `12.3` 节中讨论的两个标准构造函数。它的迭代器很弱一致。 +《《《 [下一节](03_BlockingQueue.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch14/03_BlockingQueue.md b/ch14/03_BlockingQueue.md index cce69866..b476ef30 100644 --- a/ch14/03_BlockingQueue.md +++ b/ch14/03_BlockingQueue.md @@ -1,5 +1,5 @@ - - +《《《 [返回首页](../README.md)
+《《《 [上一节](02_Implementing_Queue.md) ## BlockingQueue @@ -212,3 +212,5 @@ 就 `Collection` 方法而言,`SynchronousQueue` 表现得像一个空的 `Collection`; `Queue` 和 `BlockingQueue` 方法的行为与您对容量为零的队列的期望值相同,因此它始终为空。 迭代器方法返回一个空的迭代器,其中 `hasNext` 总是返回 `false`。 +《《《 [下一节](04_Deque.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch14/04_Deque.md b/ch14/04_Deque.md index 62c7ab78..561decea 100644 --- a/ch14/04_Deque.md +++ b/ch14/04_Deque.md @@ -1,5 +1,5 @@ - - +《《《 [返回首页](../README.md)
+《《《 [上一节](03_BlockingQueue.md) ## Deque @@ -99,3 +99,5 @@ 它具有与 `LinkedBlockingQueue` 类似的性能特征 - 队列插入和删除需要不断的时间和操作,比如包含需要遍历队列的操作,需要线性时间。迭代器是弱一致的。 +《《《 [下一节](05_Comparing_Queue_Implementations.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch14/05_Comparing_Queue_Implementations.md b/ch14/05_Comparing_Queue_Implementations.md index 0be8c9c9..1af48b05 100644 --- a/ch14/05_Comparing_Queue_Implementations.md +++ b/ch14/05_Comparing_Queue_Implementations.md @@ -1,5 +1,5 @@ - - +《《《 [返回首页](../README.md)
+《《《 [上一节](04_Deque.md) ## 比较队列实现 @@ -19,9 +19,9 @@ ArrayBlockingQueue |O(1) | O(1) | O(1) | O(1) LinkedBlockingQueue |O(1) | O(1) | O(1) | O(1) PriorityBlockingQueue |O(log n) | O(1) | O(log n) | O(1) DelayQueue |O(log n) | O(1) | O(log n) | O(1) -LinkedList |O(1) | O(1) | O(1) |O(1) -ArrayDeque |O(1) | O(1) | O(1) |O(1) -LinkedBlockingDeque |O(1) | O(1) | O(1) |O(1) +LinkedList |O(1) | O(1) | O(1) | O(1) +ArrayDeque |O(1) | O(1) | O(1) | O(1) +LinkedBlockingDeque |O(1) | O(1) | O(1) | O(1) 问题在于你是否需要阻塞方法,就像你通常为生产者 - 消费者问题所做的那样(要么是因为消费者必须通过等待来处理一个空队列,要么是因为想通过限制队列限制对它们的需求,然后生产者有时必须等待)。如果您不需要阻塞方法或队列大小的限制,请选择高效且免等待的 `ConcurrentLinkedQueue`。 @@ -29,3 +29,5 @@ LinkedBlockingDeque |O(1) | O(1) | O(1) |O(1) 否则,我们终于留下了这两者之间的选择。如果无法修复队列大小的实际上限,则必须选择 `LinkedBlockingQueue`,因为 `ArrayBlockingQueue` 总是有界的。对于有限使用,您将根据性能在两者之间进行选择。它们在图 `14-1` 中的性能特点是相同的,但这些只是顺序访问的公式;它们在并发使用中的表现是一个不同的问题。正如我们上面提到的,如果超过三个或四个线程正在服务,`LinkedBlockingQueue` 总体上比 `ArrayBlockingQueue` 更好。这符合 `LinkedBlockingQueue` 的头部和尾部被独立锁定的事实,允许同时更新两端。另一方面,`ArrayBlockingQueue` 不必为每个插入分配新的对象。如果队列性能对于您的应用程序的成功至关重要,那么您应该使用对您来说最重要的基准来衡量这两个实现:您的应用程序本身。 +《《《 [下一节](../ch15/00_Lists.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch15/00_Lists.md b/ch15/00_Lists.md index 87795979..e84a4ee6 100644 --- a/ch15/00_Lists.md +++ b/ch15/00_Lists.md @@ -1,9 +1,8 @@ - - +《《《 [返回首页](../README.md)
+《《《 [上一节](../ch14/05_Comparing_Queue_Implementations.md) ## Lists - 列表可能是实践中使用最广泛的 `Java` 集合。 一个列表是一个集合,与集合不同 - 它可以包含重复项,而不像一个队列 - 可以使用户完全可见并控制其元素的排序。 集合框架接口是 `List`(请参见图 `15-1`)。除了从 `Collection` 继承的操作外,`List` 接口还包含以下操作: @@ -67,3 +66,5 @@ 操作设置和删除工作的方式不同。它们的效果不取决于迭代器的当前位置,而是取决于它的"当前元素",使用下一个或上一个遍历的最后一个:`set` 替换当前元素,`remove` 将其删除。如果没有当前元素,或者因为迭代器刚刚创建,或者因为当前元素已被删除,这些方法将抛出 `IllegalStateException`。 +《《《 [下一节](01_Using_the_Methods_of_List.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch15/01_Using_the_Methods_of_List.md b/ch15/01_Using_the_Methods_of_List.md index 5b9ad8ee..1c41f38d 100644 --- a/ch15/01_Using_the_Methods_of_List.md +++ b/ch15/01_Using_the_Methods_of_List.md @@ -1,5 +1,5 @@ - - +《《《 [返回首页](../README.md)
+《《《 [上一节](00_Lists.md) ## 使用List的方法 @@ -71,4 +71,5 @@ 这种观点对今天来说可能会很好,但是我们必须记得在午夜时分抛弃它,因为删除和添加条目的结构性变化将使其无效。 - +《《《 [下一节](02_Implementing_List.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch15/02_Implementing_List.md b/ch15/02_Implementing_List.md index 6d802038..5ea871b1 100644 --- a/ch15/02_Implementing_List.md +++ b/ch15/02_Implementing_List.md @@ -1,5 +1,5 @@ - - +《《《 [返回首页](../README.md)
+《《《 [上一节](01_Using_the_Methods_of_List.md) ## 实现List @@ -48,3 +48,5 @@ `CopyOnWriteArraySet` 类实际上将其所有操作委托给 `CopyOnWriteArrayList` 实例,利用后者提供的原子操作 `addIfAbsent` 和 `addAllAbsent` 来启用 `Set` 方法 `add` 和 `addAll`,以避免向该集合中引入重复项。除了两个标准的构造函数(参见 `12.3` 节)之外,`CopyOnWriteArrayList` 还有一个允许使用提供的数组元素作为其初始内容创建的额外元素。它的迭代器是快照迭代器,反映了它们创建时的列表状态。 +《《《 [下一节](03_Comparing_List_Implementations.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch15/03_Comparing_List_Implementations.md b/ch15/03_Comparing_List_Implementations.md index bca2b476..b34d39c0 100644 --- a/ch15/03_Comparing_List_Implementations.md +++ b/ch15/03_Comparing_List_Implementations.md @@ -1,5 +1,5 @@ - - +《《《 [返回首页](../README.md)
+《《《 [上一节](02_Implementing_List.md) ## 比较列表实现 @@ -16,3 +16,6 @@ LinkedList |O(n) | O(1) | O(n) |O(1) | O(1) | O(1) CopyOnWrite-ArrayList |O(1) | O(n) | O(n) |O(1) | O(n) | O(n) 有可能在未来的版本中,`ArrayDeque` 将被改进以实现 `List` 接口;如果发生这种情况,它将成为单线程环境中队列和列表的选择。 + +《《《 [下一节](../ch16/00_Maps.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch16/00_Maps.md b/ch16/00_Maps.md index bfb7c654..9c1f0b08 100644 --- a/ch16/00_Maps.md +++ b/ch16/00_Maps.md @@ -1,5 +1,5 @@ - - +《《《 [返回首页](../README.md)
+《《《 [上一节](../ch15/03_Comparing_List_Implementations.md) ## Maps @@ -55,7 +55,8 @@ `entrySet` 返回的集合的成员实现了接口 `Map.Entry`,它表示键值关联并提供了一个 `setValue` 方法,可用于更改备份映射中的值。`Map.Entry` 的文档在指定实现接口的对象时只能在通过 `entrySet` 调用产生的视图迭代期间创建,并且如果在此迭代过程中修改了支持映射,则这些对象变为无效。在 `Java 6` 中,创建 `Map.Entry` 对象的这种限制性方案不够充分,因为它是 `NavigableMap` 的许多方法的返回类型(请参见第 `16.3` 节)。 - +《《《 [下一节](01_Using_the_Methods_of_Map.md)
+《《《 [返回首页](../README.md) diff --git a/ch16/01_Using_the_Methods_of_Map.md b/ch16/01_Using_the_Methods_of_Map.md index 168bba6f..ba72c4e7 100644 --- a/ch16/01_Using_the_Methods_of_Map.md +++ b/ch16/01_Using_the_Methods_of_Map.md @@ -1,5 +1,5 @@ - - +《《《 [返回首页](../README.md)
+《《《 [上一节](00_Maps.md) ## 使用 Map 的方法 @@ -68,4 +68,5 @@ 这两种方法的成本都是 `O(n)`,`Sun` 在当前的实施中具有类似的常数因子。 - +《《《 [下一节](02_Implementing_Map.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch16/02_Implementing_Map.md b/ch16/02_Implementing_Map.md index 662d4339..c69a9936 100644 --- a/ch16/02_Implementing_Map.md +++ b/ch16/02_Implementing_Map.md @@ -1,4 +1,5 @@ - +《《《 [返回首页](../README.md)
+《《《 [上一节](01_Using_the_Methods_of_Map.md) ## 实现 Map @@ -145,4 +146,5 @@ `EnumMap` 包含一个特定的键类型,它在运行时用于检查添加到地图的新条目的有效性。 这种类型由三种构造函数以不同的方式提供。 首先,它是作为一个类别令牌提供的; 在第二个中,它是从指定的 `EnumMap` 复制的。 在第三种情况下,有两种可能性:指定的 `Map` 实际上是一个 `EnumMap`,在这种情况下,它的行为与第二个构造函数类似,或者使用指定 `Map` 的第一个键的类(这就是为什么提供的 `Map` 可能不会空着)。 - +《《《 [下一节](03_SortedMap_and_NavigableMap.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch16/03_SortedMap_and_NavigableMap.md b/ch16/03_SortedMap_and_NavigableMap.md index fe45021a..ba7cfb09 100644 --- a/ch16/03_SortedMap_and_NavigableMap.md +++ b/ch16/03_SortedMap_and_NavigableMap.md @@ -1,5 +1,5 @@ - - +《《《 [返回首页](../README.md)
+《《《 [上一节](02_Implementing_Map.md) ## SortedMap 和 NavigableMap @@ -117,4 +117,5 @@ `TreeMap` 与 `TreeSet` 具有相似的性能特征:基本操作(`get`,`put` 和 `remove`)在 `O(log n)` 时间执行)。 集合视图迭代器是快速失败的。 - +《《《 [下一节](04_ConcurrentMap.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch16/04_ConcurrentMap.md b/ch16/04_ConcurrentMap.md index 18c736d3..a707fc6f 100644 --- a/ch16/04_ConcurrentMap.md +++ b/ch16/04_ConcurrentMap.md @@ -1,5 +1,5 @@ - - +《《《 [返回首页](../README.md)
+《《《 [上一节](03_SortedMap_and_NavigableMap.md) ## ConcurrentMap @@ -31,5 +31,5 @@ 忽略刚刚描述的锁定开销,`ConcurrentHashMap` 的操作成本类似于 `HashMap` 的操作成本。集合视图返回弱一致的迭代器。 - - +《《《 [下一节](05_ConcurrentNavigableMap.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch16/05_ConcurrentNavigableMap.md b/ch16/05_ConcurrentNavigableMap.md index 37b5184a..7ae18cb3 100644 --- a/ch16/05_ConcurrentNavigableMap.md +++ b/ch16/05_ConcurrentNavigableMap.md @@ -1,5 +1,5 @@ - - +《《《 [返回首页](../README.md)
+《《《 [上一节](04_ConcurrentMap.md) ## ConcurrentNavigableMap @@ -13,3 +13,5 @@ `ConcurrentSkipListMap` 和 `ConcurrentSkipListSet` 之间的关系类似于 `TreeMap` 和 `TreeSet` 之间的关系;`ConcurrentSkipListSet` 由 `ConcurrentSkipListMap` 实现,其中每个键与相同的标准值相关联,所以第 `13.2.3` 节中给出的跳过列表实现的机制和性能在这里同样适用:基本操作(`get`,`put` 和 `remove`) 在 `O(log n)` 时间执行); 集合视图上的迭代器会在下一个时间内执行。这些迭代器是快速失败的。 +《《《 [下一节](06_Comparing_Map_Implementations.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch16/06_Comparing_Map_Implementations.md b/ch16/06_Comparing_Map_Implementations.md index 9c6ec07c..7d8fd4c8 100644 --- a/ch16/06_Comparing_Map_Implementations.md +++ b/ch16/06_Comparing_Map_Implementations.md @@ -1,5 +1,5 @@ - - +《《《 [返回首页](../README.md)
+《《《 [上一节](05_ConcurrentNavigableMap.md) ## 比较 Map 的实现 @@ -23,5 +23,5 @@ ConcurrentSkipListMap| O(log n)| O(log n)| O(1)| 这就为通用地图留下了实施的选择。 对于并发应用程序,`ConcurrentHashMap` 是唯一的选择。 否则,如果您需要使用映射的插入或访问顺序(例如,将其用作缓存),则可以优先使用 `HashMap` 上的 `LinkedHashMap`(并接受其稍差的性能)。 - - +《《《 [下一节](../ch17/00_The_Collections_Class.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch17/00_The_Collections_Class.md b/ch17/00_The_Collections_Class.md index b67f1464..5fabed45 100644 --- a/ch17/00_The_Collections_Class.md +++ b/ch17/00_The_Collections_Class.md @@ -1,5 +1,5 @@ - - +《《《 [返回首页](../README.md)
+《《《 [上一节](../ch16/06_Comparing_Map_Implementations.md) ## 集合类 @@ -7,52 +7,5 @@ 集合的所有方法都是公共和静态的,所以为了可读性,我们将从各个声明中省略这些修饰符。 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +《《《 [下一节](01_Generic_Algorithms.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch17/01_Generic_Algorithms.md b/ch17/01_Generic_Algorithms.md index 12e235b5..fe14043d 100644 --- a/ch17/01_Generic_Algorithms.md +++ b/ch17/01_Generic_Algorithms.md @@ -1,5 +1,5 @@ - - +《《《 [返回首页](../README.md)
+《《《 [上一节](00_The_Collections_Class.md) ## 通用算法 @@ -64,5 +64,5 @@ void swap(List list, int i, int j) // 交换指定位置的元素 `indexOfSubList` 和 `lastIndexOfSubList` 方法的操作不需要排序列表。他们的签名允许源列表和目标列表包含任何类型的元素(请记住,这两个通配符可能代表两种不同的类型)。这些签名背后的设计决策与 `Collection` 方法 `containsAll`,`retainAll`和removeAll背后的设计决策相同(参见第 `2.6` 节)。 - - +《《《 [下一节](02_Collection_Factories.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch17/02_Collection_Factories.md b/ch17/02_Collection_Factories.md index 2c02e8fc..658380bb 100644 --- a/ch17/02_Collection_Factories.md +++ b/ch17/02_Collection_Factories.md @@ -1,5 +1,5 @@ - - +《《《 [返回首页](../README.md)
+《《《 [上一节](01_Generic_Algorithms.md) ## 收集工厂 @@ -31,4 +31,5 @@ 由于 `nCopies` 生成的列表是不可变的,它只需要包含一个物理元素来提供所需长度的列表视图。这样的列表通常被用作构建进一步集合的基础 - 例如,作为构造函数或 `addAll` 方法的参数。 - +《《《 [下一节](03_Wrappers.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch17/03_Wrappers.md b/ch17/03_Wrappers.md index 673f1287..ede4b6f7 100644 --- a/ch17/03_Wrappers.md +++ b/ch17/03_Wrappers.md @@ -1,5 +1,5 @@ - - +《《《 [返回首页](../README.md)
+《《《 [上一节](02_Collection_Factories.md) ## 包装 @@ -54,3 +54,5 @@ static SortedMap checkedSortedMap(SortedMap c, Class keyType,Class valueType) ``` +《《《 [下一节](04_Other_Methods.md)
+《《《 [返回首页](../README.md) \ No newline at end of file diff --git a/ch17/04_Other_Methods.md b/ch17/04_Other_Methods.md index d38aa723..a44b44bf 100644 --- a/ch17/04_Other_Methods.md +++ b/ch17/04_Other_Methods.md @@ -1,5 +1,5 @@ - - +《《《 [返回首页](../README.md)
+《《《 [上一节](03_Wrappers.md) ## 其他方法 @@ -92,6 +92,4 @@ 泛型和改进的集合框架可能是 `Java` 自成立以来最重大的变化。我们对这些变化感到非常兴奋,并希望我们已将这些兴奋传达给了您。我们希望您会看到泛型和集合很好地融合在一起为您的 `Java` 编程技巧提供强大的补充。 - - - +《《《 [返回首页](../README.md) \ No newline at end of file

AltStyle によって変換されたページ (->オリジナル) /