`
dingjun1
  • 浏览: 213641 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

集合框架

阅读更多
集合框架:

BitSet:???

HashMap的实现原理

添加动作:
对添加的KEY 通过一个哈希函数求值,然后根据当前存放Entry(key-value )数组的长度做一个h & (length-1)运算,
获得当前存放的位置。
这时当前位置可能已经有值存放了,产生了冲突,解决的办法是,当前Entry与旧的Entry用链表连接起来。
HashMap 中使用一个单向的链表。

获取动作:
对传入的KEY 对添加的KEY 通过一个哈希函数求值,然后根据当前存放Entry(key-value )数组的长度做一个h & (length-1)运算,
获得当前存放的位置(快的原因就在这里,不需要循环数组就直接定位)。
对当前位置的Entry中存放的KEY进行对比,如果相同(相等或equals返回真)就返回Entry的value。如果不相同,就看
Entry是否有后驱(因为产生冲突时是使用单向链表存放的),对该链表进行循环判断。

解决冲突的办法:
解决哈希表的冲突-开放地址法和链地址法
在实际应用中,无论如何构造哈希函数,冲突是无法完全避免的。

1 开放地址法


这个方法的基本思想是:当发生地址冲突时,按照某种方法继续探测哈希表中的其他存储单元,直到找到空位置为止。这个过程可用下式描述:
H i ( key ) = ( H ( key )+ d i ) mod m ( i = 1,2,…… , k ( k ≤ m – 1))
其中: H ( key ) 为关键字 key 的直接哈希地址, m 为哈希表的长度, di 为每次再探测时的地址增量。
采用这种方法时,首先计算出元素的直接哈希地址 H ( key ) ,如果该存储单元已被其他元素占用,则继续查看地址为 H ( key ) + d 2 的存储单元,如此重复直至找到某个存储单元为空时,将关键字为 key 的数据元素存放到该单元。
增量 d 可以有不同的取法,并根据其取法有不同的称呼:
( 1 ) d i = 1 , 2 , 3 , …… 线性探测再散列;
( 2 ) d i = 1^2 ,- 1^2 , 2^2 ,- 2^2 , k^2, -k^2…… 二次探测再散列;
( 3 ) d i = 伪随机序列 伪随机再散列;

例1设有哈希函数 H ( key ) = key mod 7 ,哈希表的地址空间为 0 ~ 6 ,对关键字序列( 32 , 13 , 49 , 55 , 22 , 38 , 21 )按线性探测再散列和二次探测再散列的方法分别构造哈希表。
解:
( 1 )线性探测再散列:
32 % 7 = 4 ; 13 % 7 = 6 ; 49 % 7 = 0 ;
55 % 7 = 6 发生冲突,下一个存储地址( 6 + 1 )% 7 = 0 ,仍然发生冲突,再下一个存储地址:( 6 + 2 )% 7 = 1 未发生冲突,可以存入。
22 % 7 = 1 发生冲突,下一个存储地址是:( 1 + 1 )% 7 = 2 未发生冲突;
38 % 7 = 3 ;
21 % 7 = 0 发生冲突,按照上面方法继续探测直至空间 5 ,不发生冲突,所得到的哈希表对应存储位置:
下标: 0 1 2 3 4 5 6
49 55 22 38 32 21 13
( 2 )二次探测再散列:
下标: 0 1 2 3 4 5 6
49 22 21 38 32 55 13
   注意:对于利用开放地址法处理冲突所产生的哈希表中删除一个元素时需要谨慎,不能直接地删除,因为这样将会截断其他具有相同哈希地址的元素的查找地址,所以,通常采用设定一个特殊的标志以示该元素已被删除。
2 链地址法

链地址法解决冲突的做法是:如果哈希表空间为 0 ~ m - 1 ,设置一个由 m 个指针分量组成的一维数组 ST[ m ], 凡哈希地址为 i 的数据元素都插入到头指针为 ST[ i ] 的链表中。这种方法有点近似于邻接表的基本思想,且这种方法适合于冲突比较严重的情况。

例 2 设有 8 个元素 { a,b,c,d,e,f,g,h } ,采用某种哈希函数得到的地址分别为: {0 , 2 , 4 , 1 , 0 , 8 , 7 , 2} ,当哈希表长度为 10 时,采用链地址法解决冲突的哈希表如下图所示。

HashTable:线程同步的。具体求在数组中的下标,算法上略有不同,但是原理是一样的。
当容器需扩大时,分循环原表中的每一个元素,重新计算下标,这时元素的位置和链接关系可能发生变化。相当于重新把原来的Entry重新加入到一个更长的数组当中。
从上可知:不同的容器长度,加入的先后顺序都会引起元素位置不同。更重要的时,在计算下标时会散列分布在数组中,并不是按顺序添加的。

LinkedHashMap:是HashMap的子类,重载了它的Entry的等实现,就是在添加Entry时,同时会往一个双向链表中添加元素,用来记录添加的顺序,这样在迭代时可以按顺序输出。
由于在维护散列表时,同时还会维护链表,添加时可能性能上不与HashMap,但是在遍历时,由于可能通过循环链表,不是散列表,避免了一些空值地址的访问。
在添加元素时,如果KEY相同,替换了原来的VALUE,这时链表中的Entry位置还是保持原来的位置,并不会改变,当扩大容器时也一样,链表中的顺度是不会变的。

TreeMap:其内部是红黑树的存储结构,迭代的元素是按升序排列的。可能会按照键的类的自然顺序 进行排序(参见 Comparable),或者按照创建时所提供的比较器进行排序。
return (comparator==null ? ((Comparable)k1).compareTo(k2)
                                 : comparator.compare(k1, k2));
该类不接受初始容量 和加载因子,每次空量增1,内部节点是通过指针进行连接,不像数组扩容量时需要移动原来的元素。

ArrayList:使用数组存放元素
LinkedList:使用双向链表存放元素
Vectory:与ArrayList的区别是,其操作是线程同步的。

HashSet:内部实际是使用了一个HashMap存放元素,元素被作为KEY值存放。
LinkedHashSet:内部使用LinkedHashMap

TreeSet:内部使用TreeMap进行支持。
TreeMap

Set:中存放的元素是非重复的,通过元素的equals方法进行判断是否重复,因此元素在实现是应该复写equals hashCode方法。hashCode影响元素散列分布。

List Set Map
这些子类的 iterator 或 listIterator 方法返回的迭代器是快速失败的。
Iterator迭代时,通过内部的一个版本号(modCount)进行判断是否在迭代过程中被修改(添加或修改元素)会抛异常ConcurrentModificationException,但是有些实现类是非同步的,因此不能依靠该异常进行同步的判断,这是不可靠的。异常继承于RuntimeException,因此不需要用户捕捉该异常。但是通过迭代器本身移除元素不会抛异常,

==================================================================
Collections:
提供了Read-only collections框架
unmodifiableList(List list)
unmodifiableMap
unmodifiableSet
unmodifiableSortedMap
unmodifiableSortedSet
如果对现有的集合框架进行添加、修改、删除操作会抛异常UnsupportedOperationException。
------------------------------------
synchronizedCollection
synchronizedList(List list)
synchronizedMap(Map map)
synchronizedSet(Set set)
synchronizedSortedMap(SortedMap map)
synchronizedSortedSet(SortedSet set)


分享到:
评论

相关推荐

    集合框架学习笔记

    集合框架是Java编程语言中的核心组成部分,它提供了一套高效、灵活的数据结构和算法操作,使得程序员能够方便地存储和管理对象。这篇学习笔记将深入探讨Java集合框架的基础概念、主要类库以及常见应用场景。 首先,...

    集合框架的总结

    在Java编程语言中,集合框架是开发者日常工作中不可或缺的一部分,它提供了一种高效管理对象的方式。本文将深入探讨集合框架的总结,重点关注其核心接口、类以及如何通过源码理解和利用这些工具。 首先,集合框架的...

    学士后Java集合框架和泛型课后习题答案

    Java集合框架是Java编程语言中的一个核心组成部分,它为数据存储和操作提供了丰富的类库。在Java中,集合框架主要包括接口(如List、Set、Queue)和实现这些接口的类(如ArrayList、HashSet、LinkedList等)。这个...

    Java集合框架及泛型

    Java集合框架是Java编程语言中一个非常重要的组成部分,它提供了一组高效的数据结构和操作这些数据结构的方法。泛型则是Java在J2SE 5.0版本引入的一个特性,极大地提高了代码的类型安全性和可读性。下面我们将深入...

    java集合框架图

    ### Java集合框架详解 #### 一、Java集合框架概述 Java集合框架是Java标准库的重要组成部分,它提供了存储和操作对象的各种数据结构。通过使用集合框架,开发人员可以轻松地管理不同类型的数据集,并且能够利用...

    Java集合框架详解

    Java集合框架是Java编程语言中的一个核心组成部分,它为存储、管理和操作对象提供了一套统一的接口和类。本文将深入解析Java集合框架的各个方面,包括Collection、List、Set和Map,以及它们的相关实现和使用原理。 ...

    集合框架练习.doc

    集合框架练习 在 Java 中,集合框架(Java Collections Framework)是 Java 语言中的一种数据结构,可以用来存储和操作大量数据。集合框架提供了多种数据结构,如列表、集合、映射等,可以满足不同的应用需求。下面...

    java集合 框架 泛型

    Java集合框架是Java编程语言中一个至关重要的组成部分,它为数据存储和操作提供了丰富的类库。泛型是Java 5引入的一项创新特性,极大地增强了集合框架的安全性和效率。本讲解将深入探讨这两个主题,以及与之相关的...

    《集合框架及泛型》

    BDQN ACCP 7.0 Java《集合框架及泛型》学习资料.part1

    Java集合框架总结

    ### Java集合框架总结 #### 一、Java集合框架概述 Java集合框架是Java标准库的一部分,它提供了一系列的接口和类来存储和操作各种类型的对象集合。这些接口和类遵循一致的设计模式,使得开发人员可以方便地管理和...

    Java集合框架使用总结

    ### Java集合框架使用总结 #### 前言 本文旨在为读者提供关于Java集合框架的概览性介绍,帮助理解其整体架构与设计理念。对于希望深入掌握特定接口或类使用方法的学习者,建议查阅官方提供的Java API文档。 #### ...

    Java集合框架学习笔记

    Java集合框架是Java编程语言中一个至关重要的组成部分,它提供了数据结构和算法的抽象,使得开发者可以方便地存储和管理各种类型的数据。本篇将详细探讨Java集合框架的基础知识,包括核心接口、类的层级结构以及Java...

    【Java】Java集合框架思维导图。

    xmind格式的Java集合框架学习导图,包括Collection接口/Map接口以及具体实现类。 同样包含大厂面试题,也在导图中有所体现。 能学到什么: 更加成体系的知识框架,更加全面的、系统的知识。 思维导图: 思维导图具有...

    Java集合框架.ppt

    集合是将多个元素组成一个单元的...Java集合框架,为我们提供了一套性能优良、使用方便的接口和类,我们不必再重新发明轮子,只需学会如何使用它们,就可以处理实际应用中出现的问题了Java集合框架位于java.util包中

    集合框架的使用方法

    在Java编程语言中,集合框架是处理对象集合的核心工具,它提供了一套高效、灵活的数据结构和算法。本文将深入探讨集合框架的使用方法,包括其基本概念、主要类库以及常见操作,同时也会提及一些源码分析和实用工具。...

    集合框架及泛型资料

    集合框架与泛型是Java编程语言中的核心概念,它们极大地提高了代码的可读性、安全性和效率。在Java中,集合框架是一组接口和类,它们提供了存储和操作对象的统一方式。泛型则是Java 5引入的一个特性,用于在编译时...

    集合框架源码分析

    Java集合框架是Java编程语言中的一个核心组件,它为数据组织提供了一系列的接口和类,使得数据处理变得高效且易于管理。在这个主题中,我们将深入分析集合框架的源码,理解其内部工作原理,以便更好地利用这些工具...

    数据结构和Java集合框架

    数据结构和Java集合框架是Java编程中至关重要的概念,它们是高效编程和算法设计的基础。在Java中,数据结构指的是组织、存储和管理数据的方式,而集合框架则是一组接口和类,为处理各种数据结构提供了统一的API。 ...

Global site tag (gtag.js) - Google Analytics