• [转]全面接触Java集合框架(二)


    3.2.2. Comparator接口

      若一个类不能用于实现java.lang.Comparable,或者您不喜欢缺省的Comparable行为并想提供自己的排序顺序(可能多种排序方式),你可以实现Comparator接口,从而定义一个比较器。

      (1)int compare(Object o1, Object o2): 对两个对象o1o2进行比较,如果o1位于o2的前面,则返回负值,如果在排序顺序中认为o1o2是相同的,返回0,如果o1位于o2的后面,则返回正值

      “与Comparable相似,0返回值不表示元素相等。一个0返回值只是表示两个对象排在同一位置。由Comparator用户决定如何处理。如果两个不相等的元素比较的结果为零,您首先应该确信那就是您要的结果,然后记录行为。”

      (2)boolean equals(Object obj): 指示对象obj是否和比较器相等。

      “该方法覆写Objectequals()方法,检查的是Comparator实现的等同性,不是处于比较状态下的对象。”

      3.3. SortedSet接口

      “集合框架”提供了个特殊的Set接口:SortedSet,它保持元素的有序顺序。SortedSet接口为集的视图(子集)和它的两端(即头和尾)提供了访问方法。当您处理列表的子集时,更改视图会反映到源集。此外,更改源集也会反映在子集上。发生这种情况的原因在于视图由两端的元素而不是下标元素指定,所以如果您想要一个特殊的高端元素(toElement)在子集中,您必须找到下一个元素。

      添加到SortedSet实现类的元素必须实现Comparable接口,否则您必须给它的构造函数提供一个Comparator接口的实现。TreeSet类是它的唯一一份实现。

      “因为集必须包含唯一的项,如果添加元素时比较两个元素导致了0返回值(通过ComparablecompareTo()方法或Comparatorcompare()方法),那么新元素就没有添加进去。如果两个元素相等,那还好。但如果它们不相等的话,您接下来就应该修改比较方法,让比较方法和 equals() 的效果一致。”



      (1) Comparator comparator(): 返回对元素进行排序时使用的比较器,如果使用Comparable接口的compareTo()方法对元素进行比较,则返回null

      (2) Object first(): 返回有序集合中第一个(最低)元素


      (3) Object last(): 返回有序集合中最后一个(最高)元素

      (4) SortedSet subSet(Object fromElement, Object toElement): 返回从fromElement(包括)toElement(不包括)范围内元素的SortedSet视图(子集)

      (5) SortedSet headSet(Object toElement): 返回SortedSet的一个视图,其内各元素皆小于
    toElement

      (6) SortedSet tailSet(Object fromElement): 返回SortedSet的一个视图,其内各元素皆大于或等于
    fromElement

      3.4. AbstractSet抽象类


      AbstractSet类覆盖了Object类的equals()hashCode()方法,以确保两个相等的集返回相同的哈希码。若两个集大小相等且包含相同元素,则这两个集相等。按定义,集的哈希码是集中元素哈希码的总和。因此,不论集的内部顺序如何,两个相等的集会有相同的哈希码。

      3.4.1. Object

      (1) boolean equals(Object obj): 对两个对象进行比较,以便确定它们是否相同

      (2) int hashCode(): 返回该对象的哈希码。相同的对象必须返回相同的哈希码

      3.5. HashSet类类和TreeSet

      “集合框架”支持Set接口两种普通的实现:HashSetTreeSet(TreeSet实现SortedSet接口)。在更多情况下,您会使用 HashSet 存储重复自由的集合。考虑到效率,添加到 HashSet 的对象需要采用恰当分配哈希码的方式来实现hashCode()方法。虽然大多数系统类覆盖了 Object中缺省的hashCode()equals()实现,但创建您自己的要添加到HashSet的类时,别忘了覆盖 hashCode()equals()

      当您要从集合中以有序的方式插入和抽取元素时,TreeSet实现会有用处。为了能顺利进行,添加到TreeSet的元素必须是可排序的。

      3.5.1.HashSet

      (1) HashSet(): 构建一个空的哈希集

      (2) HashSet(Collection c): 构建一个哈希集,并且添加集合c中所有元素

      (3) HashSet(int initialCapacity): 构建一个拥有特定容量的空哈希集

      (4) HashSet(int initialCapacity, float loadFactor): 构建一个拥有特定容量和加载因子的空哈希集。LoadFactor0.01.0之间的一个数

      3.5.2. TreeSet

      (1) TreeSet():构建一个空的树集

      (2) TreeSet(Collection c): 构建一个树集,并且添加集合c中所有元素

      (3) TreeSet(Comparator c): 构建一个树集,并且使用特定的比较器对其元素进行排序

      “comparator比较器没有任何数据,它只是比较方法的存放器。这种对象有时称为函数对象。函数对象通常在“运行过程中”被定义为匿名内部类的一个实例。”

      TreeSet(SortedSet s): 构建一个树集,添加有序集合s中所有元素,并且使用与有序集合s相同的比较器排序

      3.6. LinkedHashSet

      LinkedHashSet扩展HashSet。如果想跟踪添加给HashSet的元素的顺序,LinkedHashSet实现会有帮助。LinkedHashSet的迭代器按照元素的插入顺序来访问各个元素。它提供了一个可以快速访问各个元素的有序集合。同时,它也增加了实现的代价,因为哈希表元中的各个元素是通过双重链接式列表链接在一起的。

      (1) LinkedHashSet(): 构建一个空的链接式哈希集

      (2) LinkedHashSet(Collection c): 构建一个链接式哈希集,并且添加集合c中所有元素

      (3) LinkedHashSet(int initialCapacity): 构建一个拥有特定容量的空链接式哈希集

      (4) LinkedHashSet(int initialCapacity, float loadFactor): 构建一个拥有特定容量和加载因子的空链接式哈希集。LoadFactor0.01.0之间的一个数

      “为优化HashSet空间的使用,您可以调优初始容量和负载因子。TreeSet不包含调优选项,因为树总是平衡的。”

     

      4. Map接口

      Map接口不是Collection接口的继承。Map接口用于维护键/值对(key/value pairs)。该接口描述了从不重复的键到值的映射。



      (1) 添加、删除操作:

      Object put(Object key, Object value): 将互相关联的一个关键字与一个值放入该映像。如果该关键字已经存在,那么与此关键字相关的新值将取代旧值。方法返回关键字的旧值,如果关键字原先并不存在,则返回null

      Object remove(Object key): 从映像中删除与key相关的映射


      void putAll(Map t): 将来自特定映像的所有元素添加给该映像

      void clear(): 从映像中删除所有映射

      “键和值都可以为null。但是,您不能把Map作为一个键或值添加给自身。”

      (2) 查询操作:

      Object get(Object key): 获得与关键字key相关的值,并且返回与关键字key相关的对象,如果没有在该映像中找到该关键字,则返回null

      boolean containsKey(Object key): 判断映像中是否存在关键字
    key

      boolean containsValue(Object value): 判断映像中是否存在值
    value

      int size(): 返回当前映像中映射的数量


      boolean isEmpty() :判断映像中是否有任何映射

      (3) 视图操作 :处理映像中键/值对组

      Set keySet(): 返回映像中所有关键字的视图集

      “因为映射中键的集合必须是唯一的,您用Set支持。你还可以从视图中删除元素,同时,关键字和它相关的值将从源映像中被删除,但是你不能添加任何元素。”

      Collection values():返回映像中所有值的视图集

      “因为映射中值的集合不是唯一的,您用Collection支持。你还可以从视图中删除元素,同时,值和它的关键字将从源映像中被删除,但是你不能添加任何元素。”

      Set entrySet(): 返回Map.Entry对象的视图集,即映像中的关键字/值对

      “因为映射是唯一的,您用Set支持。你还可以从视图中删除元素,同时,这些元素将从源映像中被删除,但是你不能添加任何元素。”

      4.1. Map.Entry接口

      MapentrySet()方法返回一个实现Map.Entry接口的对象集合。集合中每个对象都是底层Map中一个特定的键/值对。



      通过这个集合的迭代器,您可以获得每一个条目(唯一获取方式)的键或值并对值进行更改。当条目通过迭代器返回后,除非是迭代器自身的remove()方法或者迭代器返回的条目的setValue()方法,其余对源Map外部的修改都会导致此条目集变得无效,同时产生条目行为未定义。

      (1) Object getKey(): 返回条目的关键字

      (2) Object getValue(): 返回条目的值

      (3) Object setValue(Object value): 将相关映像中的值改为value,并且返回旧值

      4.2. SortedMap接口

      “集合框架”提供了个特殊的Map接口:SortedMap,它用来保持键的有序顺序。



      SortedMap接口为映像的视图(子集),包括两个端点提供了访问方法。除了排序是作用于映射的键以外,处理SortedMap和处理SortedSet一样。

      添加到SortedMap实现类的元素必须实现Comparable接口,否则您必须给它的构造函数提供一个Comparator接口的实现。TreeMap类是它的唯一一份实现。

      “因为对于映射来说,每个键只能对应一个值,如果在添加一个键/值对时比较两个键产生了0返回值(通过ComparablecompareTo()方法或通过Comparatorcompare()方法),那么,原始键对应值被新的值替代。如果两个元素相等,那还好。但如果不相等,那么您就应该修改比较方法,让比较方法和 equals() 的效果一致。”

      (1) Comparator comparator(): 返回对关键字进行排序时使用的比较器,如果使用Comparable接口的compareTo()方法对关键字进行比较,则返回null

      (2) Object firstKey(): 返回映像中第一个(最低)关键字


      (3) Object lastKey(): 返回映像中最后一个(最高)关键字

      (4) SortedMap subMap(Object fromKey, Object toKey): 返回从fromKey(包括)toKey(不包括)范围内元素的SortedMap视图(子集)

      (5) SortedMap headMap(Object toKey): 返回SortedMap的一个视图,其内各元素的key皆小于
    toKey

      (6) SortedSet tailMap(Object fromKey): 返回SortedMap的一个视图,其内各元素的key皆大于或等于
    fromKey

      4.3. AbstractMap抽象类


      和其它抽象集合实现相似,AbstractMap 类覆盖了equals()hashCode()方法以确保两个相等映射返回相同的哈希码。如果两个映射大小相等、包含同样的键且每个键在这两个映射中对应的值都相同,则这两个映射相等。映射的哈希码是映射元素哈希码的总和,其中每个元素是Map.Entry接口的一个实现。因此,不论映射内部顺序如何,两个相等映射会报告相同的哈希码。

      4.4. HashMap类和TreeMap

      “集合框架”提供两种常规的Map实现:HashMapTreeMap (TreeMap实现SortedMap接口)。在Map 中插入、删除和定位元素,HashMap 是最好的选择。但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。使用HashMap要求添加的键类明确定义了hashCode()equals()的实现。

      这个TreeMap没有调优选项,因为该树总处于平衡状态。

      4.4.1. HashMap

      为了优化HashMap空间的使用,您可以调优初始容量和负载因子。

      (1) HashMap(): 构建一个空的哈希映像

      (2) HashMap(Map m): 构建一个哈希映像,并且添加映像m的所有映射

      (3) HashMap(int initialCapacity): 构建一个拥有特定容量的空的哈希映像

      (4) HashMap(int initialCapacity, float loadFactor): 构建一个拥有特定容量和加载因子的空的哈希映像

      4.4.2. TreeMap

      TreeMap没有调优选项,因为该树总处于平衡状态。

      (1) TreeMap():构建一个空的映像树

      (2) TreeMap(Map m): 构建一个映像树,并且添加映像m中所有元素

      (3) TreeMap(Comparator c): 构建一个映像树,并且使用特定的比较器对关键字进行排序

      (4) TreeMap(SortedMap s): 构建一个映像树,添加映像树s中所有映射,并且使用与有序映像s相同的比较器排序

      4.5. LinkedHashMap

      LinkedHashMap扩展HashMap,以插入顺序将关键字/值对添加进链接哈希映像中。象LinkedHashSet一样,LinkedHashMap内部也采用双重链接式列表。

      (1) LinkedHashMap(): 构建一个空链接哈希映像

      (2) LinkedHashMap(Map m): 构建一个链接哈希映像,并且添加映像m中所有映射

      (3) LinkedHashMap(int initialCapacity): 构建一个拥有特定容量的空的链接哈希映像

      (4) LinkedHashMap(int initialCapacity, float loadFactor): 构建一个拥有特定容量和加载因子的空的链接哈希映像

      (5) LinkedHashMap(int initialCapacity, float loadFactor,

      boolean accessOrder): 构建一个拥有特定容量、加载因子和访问顺序排序的空的链接哈希映像


      “如果将accessOrder设置为true,那么链接哈希映像将使用访问顺序而不是插入顺序来迭

      代各个映像。每次调用get或者put方法时,相关的映射便从它的当前位置上删除,然后放到链接式映像列表的结尾处(只有链接式映像列表中的位置才会受到影响,哈希表元则不受影响。哈希表映射总是待在对应于关键字的哈希码的哈希表元中)。”

      “该特性对于实现高速缓存的“删除最近最少使用”的原则很有用。例如,你可以希望将最常访问的映射保存在内存中,并且从数据库中读取不经常访问的对象。当你在表中找不到某个映射,并且该表中的映射已经放得非常满时,你可以让迭代器进入该表,将它枚举的开头几个映射删除掉。这些是最近最少使用的映射。”

      (6) protected boolean removeEldestEntry(Map.Entry eldest): 如果你想删除最老的映射,则覆盖该方法,以便返回true。当某个映射已经添加给映像之后,便调用该方法。它的默认实现方法返回false,表示默认条件下老的映射没有被删除。但是你可以重新定义本方法,以便有选择地在最老的映射符合某个条件,或者映像超过了某个大小时,返回true

      4.6. WeakHashMap

      WeakHashMapMap的一个特殊实现,它使用WeakReference(弱引用)来存放哈希表关键字。使用这种方式时,当映射的键在 WeakHashMap 的外部不再被引用时,垃圾收集器会将它回收,但它将把到达该对象的弱引用纳入一个队列。WeakHashMap的运行将定期检查该队列,以便找出新到达的弱应用。当一个弱引用到达该队列时,就表示关键字不再被任何人使用,并且它已经被收集起来。然后WeakHashMap便删除相关的映射。

      (1) WeakHashMap(): 构建一个空弱哈希映像

      (2) WeakHashMap(Map t): 构建一个弱哈希映像,并且添加映像t中所有映射

      (3) WeakHashMap(int initialCapacity): 构建一个拥有特定容量的空的弱哈希映像

      (4) WeakHashMap(int initialCapacity, float loadFactor): 构建一个拥有特定容量和加载因子的空的弱哈希映像

      4.6. IdentityHashMap

      IdentityHashMap也是Map的一个特殊实现。在这个类中,关键字的哈希码不应该由hashCode()方法来计算,而应该由System.identityHashCode方法进行计算(即使已经重新定义了hashCode方法)。这是Object.hashCode根据对象的内存地址来计算哈希码时使用的方法。另外,为了对各个对象进行比较,IdentityHashMap将使用==,而不使用equals方法。

      换句话说,不同的关键字对象,即使它们的内容相同,也被视为不同的对象。IdentityHashMap类可以用于实现对象拓扑结构转换(topology-preserving object graph transformations)(比如实现对象的串行化或深度拷贝),在进行转换时,需要一个“节点表”跟踪那些已经处理过的对象的引用。即使碰巧有对象相等,“节点表”也不应视其相等。另一个应用是维护代理对象。比如,调试工具希望在程序调试期间维护每个对象的一个代理对象。

      “IdentityHashMap类不是一般意义的Map实现!它的实现有意的违背了Map接口要求通过equals方法比较对象的约定。这个类仅使用在很少发生的需要强调等同性语义的情况。”

      (1) IdentityHashMap (): 构建一个空的全同哈希映像,默认预期最大尺寸为21

      “预期最大尺寸是映像期望把持的键/值映射的最大数目”


      (2) IdentityHashMap (Map m): 构建一个全同哈希映像,并且添加映像m中所有映射

      (3) IdentityHashMap (int expectedMaxSize): 构建一个拥有预期最大尺寸的空的全同哈希映像。放置超过预期最大尺寸的键/值映射时,将引起内部数据结构的增长,有时可能很费时

  • 相关阅读:
    ActiveSync合作关系对话框的配置
    WINCE对象存储区(object store)
    Wince 隐藏TASKBAR的方法
    Wince输入法换肤换语言机制
    poj 3080 Blue Jeans 解题报告
    codeforces A. Vasily the Bear and Triangle 解题报告
    hdu 1050 Moving Tables 解题报告
    hdu 1113 Word Amalgamation 解题报告
    codeforces A. IQ Test 解题报告
    poj 1007 DNA Sorting 解题报告
  • 原文地址:https://www.cnblogs.com/eflylab/p/625230.html
Copyright © 2020-2023  润新知