J2SE 1.4 为 Java Collections Framework 引入了两个新实现, LinkedHashSet 和 LinkedHashMap 。添加这两个新实现的好处是散列集合现在可以维护贯穿其元素的两条路径。除标准的散列关系之外,现在还有一个可遍历整个集合的链表。正常情况下,这个新的第二路径会遵循插入顺序,这意味着集合的迭代器将按照元素的插入顺序返回元素(而不按它们的散列码将其组合成一个集合的顺序),但 LinkedHashMap 支持第二种排序选项:按存取顺序而非插入顺序维护链表。
我们来看一下这些新类是如何工作的。
开始
开始使用这些新类非常容易。 只需导入 java.util 包并找到一组要使用的项目。在我们的示例中,我们将使用日历表的月份。在使用集时我们将使用英语月份名称,在使用映射表时用英语和意大利语的月份名称。
清单 1. 开始定义类
import java.util.*;
public class OrderedAccess {
public static void main(String args[]) {
String months[] =
new DateFormatSymbols().getMonths();
String italianMonths[] =
new DateFormatSymbols(Locale.ITALIAN).getMonths();
}
}
我将假定您已经知道了英语月份的名称和顺序。对于那些不熟悉意大利语月份名称的人们,它们是:Gennaio、Febbraio、Marzo、Aprile、Maggio、Giugno、Luglio、Agosto、Settembre、Ottobre、Novembre 和 Dicembre, 虽然由于某些原因 getMonths() 返回的名称不是大写的。
使用新 HashSet
LinkedHashSet 是基本 HashSet 类的一个子类。因此, 凡是 HashSet 能做的工作, LinkedHashSet 也能做到。 类中没有新方法。您能得到的只有 4 个构造函数:
LinkedHashSet()
LinkedHashSet(Collection c)
LinkedHashSet(int initialCapacity)
LinkedHashSet(int initialCapacity, float loadFactor)
要向集中添加元素,我们可以为每个元素调用 add() ,或创建一个 Collection 并将它传递到构造函数。因为数组中已经有了元素,所以最简单的机制就是使用 Arrays.asList() ,它会返回一个包装成 List 中的数组,同时维持原始数组的顺序。通过将 list 传递到构造函数,我们可以很轻松地将相同的 list 添加到 LinkedHashSet 和简单的 HashSet 中。
清单 2. 填充集
List list = Arrays.asList(months);
Set orderedSet = new LinkedHashSet(list);
Set unorderedSet = new HashSet(list);
在填满了集之后,我们可以检查它们的元素,看看链接的集是否按插入顺序维护其元素, 然后与标准散列集比较结果。您可以通过集的 iterator() 手工迭代每个集的各个元素,或只调用 toString() 方法(隐式地),实际上就是它为我们做了那些工作。
清单 3. 显示集结果
System.out.println("Ordered: " + orderedSet);
System.out.println("Unordered: " + unorderedSet);