驯服Tiger – 荟萃框架
当前位置:以往代写 > JAVA 教程 >驯服Tiger – 荟萃框架
2019-06-14

驯服Tiger – 荟萃框架

驯服Tiger – 荟萃框架

副标题#e#

JDK 5.0 中最吸引人的处地址于荟萃框架的一些最突出的特性上,譬喻:支 持泛型的语言级别上的新变革,以及可以在 java.util.concurrent 包中找到的 并发荟萃东西包。实际上,以前在 developerWorks 上的“驯服 Tiger: 并发集 合”和“先容 JDK 5.0 中的泛型”这两篇教程中先容了上述特性。可是其他增 强还没有获得足够的重视。在本文中,我将研究其他三个变革:更新过的 Arrays 和 Collections 类、新的 Queue 接口以及它的 PriorityQueue 实现。

数组(Array)

Arrays 类提供了一系列处理惩罚数组的静态东西要领,这些索引的数据布局的大 小是牢靠的。在 5.0 版本之前,Arrays 类拥有针对原始数据库范例和通用 Object 范例的每种差异数组范例的 binarySearch()、equals()、fill() 和 sort() 要领。用于将 Object 数组转换成 List 的附加 asList() 要领仍然有 用。Tiger 为所有数组添加了 hashCode() 和 toString() 要领,还添加了特定 于 Object 数组的 deepEquals()、deepHashCode() 和 deepToString() 要领。 总计有 21 个新要领可用:

public static boolean deepEquals(Object[] a1, Object[] a2)

public static int deepHashCode(Object[] a)

public static String deepToString(Object[] a)

public static int hashCode(boolean[] a)

public static int hashCode(byte[] a)

public static int hashCode(char[] a)

public static int hashCode(double[] a)

public static int hashCode(float[] a)

public static int hashCode(int[] a)

public static int hashCode(long[] a)

public static int hashCode(Object[] a)

public static int hashCode(short[] a)

public static String toString(boolean[] a)

public static String toString(byte[] a)

public static String toString(char[] a)

public static String toString(double[] a)

public static String toString(float[] a)

public static String toString(int[] a)

public static String toString(long[] a)

public static String toString(Object[] a)

public static String toString(short[] a)


#p#副标题#e#

自从荟萃框架初次呈此刻 J2SE 1.2 中以来,人们第一次对实用东西类举办 了变动。我无法确定为什么 Sun 要等这么久才举办变动,可是对付可用的辅佐 器要领系列来说,这些变动是受接待的添加。

新添加的第一个要领是 hashCode()。对付任意数组范例,都可以挪用 Arrays.hashCode(arrayVar) 要领来得到名目精采的哈希码。这个哈希码可以用 作 HashMap 可能其他相关目标的键。假如您不知道如何生成精采的哈希码,那 么最好利用 Arrays 类,它能发生更少斗嘴。Arrays 类生成等价于拥有沟通元 素的 List 的代码。

在建设本身的类时,既需要提供 equals() 要领,又需要提供 hashCode() 要领。在 Arrays 的新要领 hashCode() 的辅佐下,可觉得任何当地数组范例生 成哈希码,而不消在每次需要它的时候折腾您本身。

所有数组范例都可用的另一个要领是 toString()。对付任何数组范例,都可 以挪用 Arrays.toString(arrayVar) 得到逗号脱离的元素列表,列表用方括号 困绕,如清单 1 的措施所示:

清单 1. 用 Arrays.toString 生成字符串

import java.util.Arrays;
public class ArgsToString {
  public static void main(String args[]) {
   System.out.println(Arrays.toString(args));
  }
}

清单 2 显示了功效:

清单 2. 清单 1 的功效

>java ArgsToString One Two Three
  [One, Two, Three]

新的 deepEquals()、deepHashCode() 和 deepToString() 要领的事情方法 雷同于它们那些非深度(non-deep)的同类,但它们不只会停下手来处理惩罚顶级数 组的每个元素,还会更深入地研究生成功效的多维数组。

固然不是一个新要领,但 asList() 要领在 5.0 的事情方法有所差异。以前 ,这个要领接管 Object[] 数组作为它的参数。此刻,因为 Tiger 的可变参数 列表特性,任何用逗号脱离的列表都可以接管,如清单 3 所示:

清单 3. Arrays.asList 的区别

import java.util.Arrays;
public class AsList {
  public static void main(String args[]) {
   // Before
   List before = Arrays.asList(args);
   // After
   List after = Arrays.asList("One", "Two", "Three");
  }
}

假如通报给呼吁行的元素差异,清单 3 中的两个示例没须要发生同样的功效 ,可是它确实展示了 Tiger 在语言级别上的变革如何扩展了 Arrays 原有的 asList() 要领。

荟萃

Arrays 用于处理惩罚差异荟萃的帮助类是 Collections 类。同样,这个类也不 是一个新类,可是该类的特性已经针对 5.0 作了扩展。此刻有 13 个新要领:

checkedCollection()

checkedSet()

checkedSortedSet()

checkedList()

checkedMap()

checkedSortedMap()

emptySet()

emptyList()

emptyMap()

reverseOrder()

frequency()

disjoint()

addAll()

#p#副标题#e#

#p#分页标题#e#

个中 6 个 checked*() 要领事情起来与 6 个 synchronized*() 和 unmodifiable*() 要领雷同。利用 synchronized*() 要领时,要向该要领提供 一个荟萃,然后该要领将返回同一个荟萃的同步的、线程安详的版本。利用 unmodifiable*() 要领时,获得的是指定荟萃的只读视图。除了荟萃参数之外, checked*() 操纵大概还要求第二个可能第三个参数(如清单 4 所示),并返回 该荟萃的动态的范例安详视图:

清单 4. 检测后的荟萃

public static <E> Collection<E> checkedCollection(
   Collection<E> c, Class<E> type)
  public static <E> Set<E> checkedSet(
   Set<E> s, Class<E> type)
  public static <E> SortedSet<E> checkedSortedSet(
   SortedSet<E> s, Class<E> type)
  public static <E> List<E> checkedList(
   List<E> list, Class<E> type)
  public static <K,V> Map<K,V> checkedMap(
   Map<K,V> m, Class<K> keyType, Class<V> valueType)
  public static <K,V> SortedMap<K,V> checkedSortedMap (
   SortedMap<K,V> m, Class<K> keyType, Class<V> valueType)

利用 Java 5.0 平台,您大概觉得:由于将荟萃声明为通用荟萃 (Collection<String> c = new HashSet<String>();),所以不 需要举办运行时检测了。可是假如向东西要领通报 String 版本的 HashSet,而 东西要领只能处理惩罚非通用的 Set,那么该要领大概就会错误地向荟萃添加一个非 String 元素。通过姑且修改措施,用 Collection<String> c = Collections.checkedCollection(new HashSet<String>(), String.class); 添加运行时查抄,您可以迅速发明问题的来源。

三个 empty*() 要领 —— emptySet()、emptyList() 和 emptyMap() —— 生成空的不行改变的荟萃。固然也可以用 new ArraySet() 这样的要领建设空集 合,可是还要通过某个 unmodifiable*() 要领才气确保新荟萃是不行改变的。 empty 要领用更抱负的方法提供了空的只读荟萃。

行列(Queue)接口

5.0 荟萃框架较大的一个改变就是添加了新的基接口 Queue。固然这个接口 是在“并发荟萃”能力 (请参阅 参考资料)中描写的,但它的应用并不限于并 发。在计较机科学中,行列数据布局是根基的先进先出(FIFO) 布局。项目添 加到尾部,而且要从顶部删除。不只能添加和删除元素,还能查察行列中有哪些 元素。清单 5 显示了 Queue 接口的 5 个要领:

清单 5. Queue 接口

public boolean offer(Object element)
  public Object remove()
  public Object poll()
  public Object element()
  public Object peek()

#p#副标题#e#

请记着,Queue 是从 Collection 接口扩展的,所以实现 Queue 接口也就实 现了 Collection。在利用 Queue 的实现时,该当将本身限制在接口的要领上。 譬喻,向 Queue 添加元素可以用 Collection 的 add() 要领来实现,它在失败 时会抛出未检测异常。相反,假如巨细有限的行列满了,那么 offer() 要了解 返回 false,而不需要处理惩罚行列满的异常。

java.util.concurrent 包中具有 Queue 接口的多个实现,但并不包括所有 实现。LinkedList 类针对 JDK 5.0 的 Queue 接口作了批改,而 PriorityQueue 是随 JDK 5.0 添加进来的。余下的实现 —— ArrayBlockingQueue、ConcurrentLinkedQueue、DelayQueue、 LinkedBlockingQueue、PriorityBlockingQueue 和 SynchronousQueue —— 都 是 java.util.concurrent 包的构成部门。

因为 LinkedList 不是新事物,所以我们来看一下新的 PriorityQueue 类。 如清单 6 所示,可以用 6 种要领建设它。在不能利用 Comparator 时,可以使 用元素的自然顺序来确定优先级。假如元素没有实现 Comparable 接口,那么就 会发生运行时错误:

清单 6. PriorityQueue 结构函数

PriorityQueue()
  PriorityQueue(Collection<? extends E> c)
  PriorityQueue(int initialCapacity)
  PriorityQueue(int initialCapacity, Comparator<? super E> comparator)
  PriorityQueue(PriorityQueue<? extends E> c)
  PriorityQueue(SortedSet<? extends E> c)

为了演示 PriorityQueue 的用法,清单 7 中的措施添加了所有呼吁行元素 ,并按字母顺序处理惩罚它们。由于行列布局是 LinkedList,所以顺序该当是典范 的 FIFO 顺序,可是 PriorityQueue 将按照优先级对元素举办排序:

清单 7. PriorityQueue 的用法

#p#分页标题#e#

import java.util.*;
import java.util.concurrent.*;
public class Priority {
  public static void main(String args[]) {
   Queue<String> queue =
    new PriorityQueue<String>(Arrays.asList(args));
   String element;
   while ((element = queue.poll()) != null) {
     System.out.println(element);
   }
  }
}

清单 8 显示了用呼吁行 one two three four 运行措施之后的输出 :

清单 8. 清单 7 的功效

>java Priority one two three four
  four
  one
  three
  two

关于新的 Queue 接口,有件事需要提一下,这件事与 Collections 类有关 :要领 checkedQueue()、emptyQueue()、synchronizedQueue() 和 unmodifiableQueue() 全都是 Collections 类中所缺少的。按照 bug 陈诉,除 了 checkedQueue() 之外,所有类都是存心缺失的。对付 synchronizedQueue() ,并发荟萃是比纯粹的包装器更好的选择。其他要领例被认为不是必须的。也许 Tiger/6.0 版本中会添加 checkedQueue()(和 checkedBlockingQueue()) 。

本文配套源码

    关键字:

在线提交作业