再论JAVA中的核心数据——Map&Set
2012-11-12 14:08
369 查看
Map,顾名思义,是一种映射的机制
在JAVA中,常用的有Hashtable,HashMap,LinkedHashMap,TreeMap
Hashtable的大部分方法都做了同步,是线程安全的,HashMap是非线程安全的;而且Hashtable不允许key/value为Null,而HashMap可以
1、HashMap
HashMap底层的数据结构还是数组,内存地址就是数组的下标,HashMap中的哈希算法如下:
^表示异或操作,>>>表示无符号右移
我们来看几个例子,大家就知道哈希算法的精妙之处了:
不知道大家有没有看出来这里的精妙,哈希算法的精髓就是平均分布,我们可以看到哈希值的二进制中的1已经平均分布了,这里采用位运算符而不采用逻辑运算符,也是为了性能的提升。
自己可以动手试试了。
那么以上是得到了key的哈希值了,那么下面,我们如何通过key来获取value呢?
学过数据结构的都知道,哈希存在冲突问题,那么如何解决呢?
HashMap是采用数组+链表的方式来实现,所以同一下标有多个数据元素的时候就在该下标形成了一个链表。。。
后来的元素不断插入在链表头部
HashMap=ArrayList+LinkedList
HashMap默认初始化大小是16,负载因子是0.75,
负载因子=元素个数/内部数组总大小,其实就是填充率
HashMap的扩容,同样会进行数组的整体复制,所以扩容操作要注意
2、LinkedHashMap
由于HashMap的无序性,从来出现了LinkedHashMap
是基于元素进入集合的顺序或被访问的先后顺序排序
3、TreeMap
是基于元素的固有顺序
实现Comparable接口,重写compareTo()方法
set
set的实现都只是对map的一种封装而已
RandomAccess
所有基于数组的List都实现了此接口,而基于链表的没有,很简单,只有数组才能快速定位访问某个元素,而链表需要遍历
所以在代码中,当需要查找元素操作时,你可以先判断list instanceof RandomAccess,使用不同的遍历操作
个人链接:
--------------------------------
新浪微博:http://weibo.com/cwtree
人人首页:www.renren.com/treelovexiaobei
优酷空间: http://i.youku.com/cwtree
科大首页:http://home.ustc.edu.cn/~cwtree/
--------------------------------
在JAVA中,常用的有Hashtable,HashMap,LinkedHashMap,TreeMap
Hashtable的大部分方法都做了同步,是线程安全的,HashMap是非线程安全的;而且Hashtable不允许key/value为Null,而HashMap可以
1、HashMap
HashMap底层的数据结构还是数组,内存地址就是数组的下标,HashMap中的哈希算法如下:
static int hash(int h) { h ^= (h>>>20)^(h>>>12); return h^(h>>>7)^(h>>>4); }
^表示异或操作,>>>表示无符号右移
我们来看几个例子,大家就知道哈希算法的精妙之处了:
a=32768 a的二进制:1000000000000000 a的哈希值:35080 a的哈希值的二进制:1000100100001000 a=65536 a的二进制:10000000000000000 a的哈希值:70161 a的哈希值的二进制:10001001000010001 a=524288 a的二进制:10000000000000000000 a的哈希值:561289 a的哈希值的二进制:10001001000010001001 a=123456789 a的二进制:111010110111100110100010101 a的哈希值:119583776 a的哈希值的二进制:111001000001011010000100000
不知道大家有没有看出来这里的精妙,哈希算法的精髓就是平均分布,我们可以看到哈希值的二进制中的1已经平均分布了,这里采用位运算符而不采用逻辑运算符,也是为了性能的提升。
自己可以动手试试了。
那么以上是得到了key的哈希值了,那么下面,我们如何通过key来获取value呢?
static int indexFor(int h,int lengh) { return h&(lengh-1); }通过将哈希值与数组最后一个元素下标做与运算,得到的值就是value的数组下标,直接获取即可。
学过数据结构的都知道,哈希存在冲突问题,那么如何解决呢?
HashMap是采用数组+链表的方式来实现,所以同一下标有多个数据元素的时候就在该下标形成了一个链表。。。
后来的元素不断插入在链表头部
HashMap=ArrayList+LinkedList
HashMap默认初始化大小是16,负载因子是0.75,
负载因子=元素个数/内部数组总大小,其实就是填充率
HashMap的扩容,同样会进行数组的整体复制,所以扩容操作要注意
2、LinkedHashMap
由于HashMap的无序性,从来出现了LinkedHashMap
是基于元素进入集合的顺序或被访问的先后顺序排序
3、TreeMap
是基于元素的固有顺序
实现Comparable接口,重写compareTo()方法
set
set的实现都只是对map的一种封装而已
RandomAccess
所有基于数组的List都实现了此接口,而基于链表的没有,很简单,只有数组才能快速定位访问某个元素,而链表需要遍历
所以在代码中,当需要查找元素操作时,你可以先判断list instanceof RandomAccess,使用不同的遍历操作
个人链接:
--------------------------------
新浪微博:http://weibo.com/cwtree
人人首页:www.renren.com/treelovexiaobei
优酷空间: http://i.youku.com/cwtree
科大首页:http://home.ustc.edu.cn/~cwtree/
--------------------------------
相关文章推荐
- Java核心数据结构(List,Map,Set)使用技巧与优化
- Java集合转换【List<-->数组、List<-->Set、数组<-->Set、Map-->Set、Map-->List】
- 数据结构(Java)——Set和Map的应用
- 再论JAVA中核心数据结构——List
- mybatis中的resultType="java.util.Map",返回有重复数据
- 数据存储——浅谈Java中的Set、List、Map的区别
- c++如何往map<string, set<string> > 添加数据
- java 数据集合(set、map、list)
- 黑马程序员_java集合(1) Collection & List & Set & Map
- java 中的集合(八) Set&&Map相关
- java4Android(20):类集框架->Set/Map/List->ArrayList简单实例
- Java 集合SortedSet&SortedMap讲解
- java中Json数据和map数据的转换&&解析服务器返回的json
- Java集合转换【List<-->数组、List<-->Set、数组<-->Set、Map-->Set、Map-->List】
- 利用java集合Set、Map、List等的特性,分类统计各组数据的数量
- Java之List&Set&Map详解
- 集合转换java:【List<-->数组、List<-->Set、数组<-->Set、Map-->Set、Map-->List】
- javaweb --- jsp页面遍历list<map>类型的数据